102#define DEBUG_TYPE "ppc-lowering"
141 bool isPPC64 = Subtarget.
isPPC64();
182 if (!Subtarget.
hasSPE()) {
191 for (
MVT VT : ScalarIntVTs) {
201 if (isPPC64 || Subtarget.
hasFPCVT()) {
294 !(TM.Options.UnsafeFPMath && Subtarget.
hasFRSQRTE() &&
299 !(TM.Options.UnsafeFPMath && Subtarget.
hasFRSQRTES() &&
707 if (TM.Options.UnsafeFPMath || Subtarget.
hasVSX()) {
1055 if (TM.Options.UnsafeFPMath) {
1129 if (TM.Options.UnsafeFPMath) {
1233 unsigned MaxMaxAlign) {
1234 if (MaxAlign == MaxMaxAlign)
1236 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1237 if (MaxMaxAlign >= 32 && VTy->getBitWidth() >= 256)
1239 else if (VTy->getBitWidth() >= 128 && MaxAlign < 16)
1241 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1242 unsigned EltAlign = 0;
1244 if (EltAlign > MaxAlign)
1245 MaxAlign = EltAlign;
1246 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1247 for (
auto *EltTy : STy->elements()) {
1248 unsigned EltAlign = 0;
1250 if (EltAlign > MaxAlign)
1251 MaxAlign = EltAlign;
1252 if (MaxAlign == MaxMaxAlign)
1268 unsigned Align = Subtarget.
isPPC64() ? 8 : 4;
1279 return Subtarget.
hasSPE();
1299 return "PPCISD::FP_TO_UINT_IN_VSR,";
1301 return "PPCISD::FP_TO_SINT_IN_VSR";
1356 return "PPCISD::ST_VSR_SCAL_INT";
1427 return CFP->getValueAPF().isZero();
1431 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1432 return CFP->getValueAPF().isZero();
1440 return Op < 0 || Op == Val;
1452 if (ShuffleKind == 0) {
1455 for (
unsigned i = 0; i != 16; ++i)
1458 }
else if (ShuffleKind == 2) {
1461 for (
unsigned i = 0; i != 16; ++i)
1464 }
else if (ShuffleKind == 1) {
1465 unsigned j = IsLE ? 0 : 1;
1466 for (
unsigned i = 0; i != 8; ++i)
1483 if (ShuffleKind == 0) {
1486 for (
unsigned i = 0; i != 16; i += 2)
1490 }
else if (ShuffleKind == 2) {
1493 for (
unsigned i = 0; i != 16; i += 2)
1497 }
else if (ShuffleKind == 1) {
1498 unsigned j = IsLE ? 0 : 2;
1499 for (
unsigned i = 0; i != 8; i += 2)
1525 if (ShuffleKind == 0) {
1528 for (
unsigned i = 0; i != 16; i += 4)
1534 }
else if (ShuffleKind == 2) {
1537 for (
unsigned i = 0; i != 16; i += 4)
1543 }
else if (ShuffleKind == 1) {
1544 unsigned j = IsLE ? 0 : 4;
1545 for (
unsigned i = 0; i != 8; i += 4)
1562 unsigned LHSStart,
unsigned RHSStart) {
1565 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1566 "Unsupported merge size!");
1568 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1569 for (
unsigned j = 0; j != UnitSize; ++j) {
1571 LHSStart+j+i*UnitSize) ||
1573 RHSStart+j+i*UnitSize))
1588 if (ShuffleKind == 1)
1590 else if (ShuffleKind == 2)
1595 if (ShuffleKind == 1)
1597 else if (ShuffleKind == 0)
1613 if (ShuffleKind == 1)
1615 else if (ShuffleKind == 2)
1620 if (ShuffleKind == 1)
1622 else if (ShuffleKind == 0)
1672 unsigned RHSStartValue) {
1676 for (
unsigned i = 0; i < 2; ++i)
1677 for (
unsigned j = 0; j < 4; ++j)
1679 i*RHSStartValue+j+IndexOffset) ||
1681 i*RHSStartValue+j+IndexOffset+8))
1703 unsigned indexOffset = CheckEven ? 4 : 0;
1704 if (ShuffleKind == 1)
1706 else if (ShuffleKind == 2)
1712 unsigned indexOffset = CheckEven ? 0 : 4;
1713 if (ShuffleKind == 1)
1715 else if (ShuffleKind == 0)
1738 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
1741 if (i == 16)
return -1;
1746 if (ShiftAmt < i)
return -1;
1751 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
1753 for (++i; i != 16; ++i)
1756 }
else if (ShuffleKind == 1) {
1758 for (++i; i != 16; ++i)
1765 ShiftAmt = 16 - ShiftAmt;
1775 (EltSize == 1 || EltSize == 2 || EltSize == 4));
1779 if (
N->getMaskElt(0) % EltSize != 0)
1784 unsigned ElementBase =
N->getMaskElt(0);
1787 if (ElementBase >= 16)
1792 for (
unsigned i = 1; i != EltSize; ++i)
1793 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
1796 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
1797 if (
N->getMaskElt(i) < 0)
continue;
1798 for (
unsigned j = 0; j != EltSize; ++j)
1799 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
1816 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
1817 "Unexpected element width.");
1818 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
1820 unsigned NumOfElem = 16 / Width;
1821 unsigned MaskVal[16];
1822 for (
unsigned i = 0; i < NumOfElem; ++i) {
1823 MaskVal[0] =
N->getMaskElt(i * Width);
1824 if ((StepLen == 1) && (MaskVal[0] % Width)) {
1826 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
1830 for (
unsigned int j = 1; j < Width; ++j) {
1831 MaskVal[j] =
N->getMaskElt(i * Width + j);
1832 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
1842 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
1847 unsigned M0 =
N->getMaskElt(0) / 4;
1848 unsigned M1 =
N->getMaskElt(4) / 4;
1849 unsigned M2 =
N->getMaskElt(8) / 4;
1850 unsigned M3 =
N->getMaskElt(12) / 4;
1851 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
1852 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
1857 if ((M0 > 3 && M1 == 1 && M2 == 2 && M3 == 3) ||
1858 (M0 < 4 && M1 == 5 && M2 == 6 && M3 == 7)) {
1859 ShiftElts = IsLE ? LittleEndianShifts[M0 & 0x3] : BigEndianShifts[M0 & 0x3];
1860 InsertAtByte = IsLE ? 12 : 0;
1865 if ((M1 > 3 && M0 == 0 && M2 == 2 && M3 == 3) ||
1866 (M1 < 4 && M0 == 4 && M2 == 6 && M3 == 7)) {
1867 ShiftElts = IsLE ? LittleEndianShifts[M1 & 0x3] : BigEndianShifts[M1 & 0x3];
1868 InsertAtByte = IsLE ? 8 : 4;
1873 if ((M2 > 3 && M0 == 0 && M1 == 1 && M3 == 3) ||
1874 (M2 < 4 && M0 == 4 && M1 == 5 && M3 == 7)) {
1875 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
1876 InsertAtByte = IsLE ? 4 : 8;
1881 if ((M3 > 3 && M0 == 0 && M1 == 1 && M2 == 2) ||
1882 (M3 < 4 && M0 == 4 && M1 == 5 && M2 == 6)) {
1883 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
1884 InsertAtByte = IsLE ? 0 : 12;
1891 if (
N->getOperand(1).isUndef()) {
1894 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
1895 if (M0 == XXINSERTWSrcElem && M1 == 1 && M2 == 2 && M3 == 3) {
1896 InsertAtByte = IsLE ? 12 : 0;
1899 if (M0 == 0 && M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
1900 InsertAtByte = IsLE ? 8 : 4;
1903 if (M0 == 0 && M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
1904 InsertAtByte = IsLE ? 4 : 8;
1907 if (M0 == 0 && M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
1908 InsertAtByte = IsLE ? 0 : 12;
1917 bool &Swap,
bool IsLE) {
1924 unsigned M0 =
N->getMaskElt(0) / 4;
1925 unsigned M1 =
N->getMaskElt(4) / 4;
1926 unsigned M2 =
N->getMaskElt(8) / 4;
1927 unsigned M3 =
N->getMaskElt(12) / 4;
1931 if (
N->getOperand(1).isUndef()) {
1932 assert(M0 < 4 &&
"Indexing into an undef vector?");
1933 if (M1 != (M0 + 1) % 4 || M2 != (M1 + 1) % 4 || M3 != (M2 + 1) % 4)
1936 ShiftElts = IsLE ? (4 - M0) % 4 : M0;
1942 if (M1 != (M0 + 1) % 8 || M2 != (M1 + 1) % 8 || M3 != (M2 + 1) % 8)
1946 if (M0 == 0 || M0 == 7 || M0 == 6 || M0 == 5) {
1951 ShiftElts = (8 - M0) % 8;
1952 }
else if (M0 == 4 || M0 == 3 || M0 == 2 || M0 == 1) {
1957 ShiftElts = (4 - M0) % 4;
1962 if (M0 == 0 || M0 == 1 || M0 == 2 || M0 == 3) {
1967 }
else if (M0 == 4 || M0 == 5 || M0 == 6 || M0 == 7) {
1984 for (
int i = 0; i < 16; i += Width)
1985 if (
N->getMaskElt(i) != i + Width - 1)
2016 bool &Swap,
bool IsLE) {
2023 unsigned M0 =
N->getMaskElt(0) / 8;
2024 unsigned M1 =
N->getMaskElt(8) / 8;
2025 assert(((M0 | M1) < 4) &&
"A mask element out of bounds?");
2029 if (
N->getOperand(1).isUndef()) {
2030 if ((M0 | M1) < 2) {
2031 DM = IsLE ? (((~M1) & 1) << 1) + ((~M0) & 1) : (M0 << 1) + (M1 & 1);
2039 if (M0 > 1 && M1 < 2) {
2041 }
else if (M0 < 2 && M1 > 1) {
2049 DM = (((~M1) & 1) << 1) + ((~M0) & 1);
2052 if (M0 < 2 && M1 > 1) {
2054 }
else if (M0 > 1 && M1 < 2) {
2062 DM = (M0 << 1) + (M1 & 1);
2075 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2091 unsigned EltSize = 16/
N->getNumOperands();
2092 if (EltSize < ByteSize) {
2093 unsigned Multiple = ByteSize/EltSize;
2095 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2098 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2099 if (
N->getOperand(i).isUndef())
continue;
2101 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2103 if (!UniquedVals[i&(Multiple-1)].getNode())
2104 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2105 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2115 bool LeadingZero =
true;
2116 bool LeadingOnes =
true;
2117 for (
unsigned i = 0; i != Multiple-1; ++i) {
2118 if (!UniquedVals[i].getNode())
continue;
2125 if (!UniquedVals[Multiple-1].getNode())
2127 int Val = cast<ConstantSDNode>(UniquedVals[Multiple-1])->getZExtValue();
2132 if (!UniquedVals[Multiple-1].getNode())
2134 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2143 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2144 if (
N->getOperand(i).isUndef())
continue;
2146 OpVal =
N->getOperand(i);
2147 else if (OpVal !=
N->getOperand(i))
2153 unsigned ValSizeInBytes = EltSize;
2156 Value = CN->getZExtValue();
2158 assert(CN->getValueType(0) ==
MVT::f32 &&
"Only one legal FP vector type!");
2165 if (ValSizeInBytes < ByteSize)
return SDValue();
2176 if (MaskVal == 0)
return SDValue();
2179 if (SignExtend32<5>(MaskVal) == MaskVal)
2187 EVT VT =
N->getValueType(0);
2195 for (i = 0; i != 4 && SVOp->
getMaskElt(i) < 0; ++i)
2198 if (i == 4)
return -1;
2203 if (ShiftAmt < i)
return -1;
2207 for (++i; i != 4; ++i)
2223 if (!isa<ConstantSDNode>(
N))
2226 Imm = (int16_t)cast<ConstantSDNode>(
N)->getZExtValue();
2228 return Imm == (int32_t)cast<ConstantSDNode>(
N)->getZExtValue();
2230 return Imm == (int64_t)cast<ConstantSDNode>(
N)->getZExtValue();
2244 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(*UI)) {
2245 if (Memop->getMemoryVT() ==
MVT::f64) {
2246 Base =
N.getOperand(0);
2247 Index =
N.getOperand(1);
2263 unsigned EncodingAlignment)
const {
2271 (!EncodingAlignment || !(imm % EncodingAlignment)))
2276 Base =
N.getOperand(0);
2277 Index =
N.getOperand(1);
2279 }
else if (
N.getOpcode() ==
ISD::OR) {
2281 (!EncodingAlignment || !(imm % EncodingAlignment)))
2293 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2294 Base =
N.getOperand(0);
2295 Index =
N.getOperand(1);
2351 unsigned EncodingAlignment)
const {
2361 (!EncodingAlignment || (imm % EncodingAlignment) == 0)) {
2367 Base =
N.getOperand(0);
2370 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2372 assert(!cast<ConstantSDNode>(
N.getOperand(1).getOperand(1))->getZExtValue()
2373 &&
"Cannot handle constant offsets yet!");
2374 Disp =
N.getOperand(1).getOperand(0);
2379 Base =
N.getOperand(0);
2382 }
else if (
N.getOpcode() ==
ISD::OR) {
2385 (!EncodingAlignment || (imm % EncodingAlignment) == 0)) {
2395 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2399 Base =
N.getOperand(0);
2412 (!EncodingAlignment || (Imm % EncodingAlignment) == 0)) {
2415 CN->getValueType(0));
2420 if ((CN->getValueType(0) ==
MVT::i32 ||
2421 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2422 (!EncodingAlignment || (CN->getZExtValue() % EncodingAlignment) == 0)) {
2423 int Addr = (int)CN->getZExtValue();
2464 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2465 Base =
N.getOperand(0);
2466 Index =
N.getOperand(1);
2488 EVT MemVT = LD->getMemoryVT();
2495 if (!ST.hasP8Vector())
2500 if (!ST.hasP9Vector())
2513 if (UI.getUse().get().getResNo() == 0 &&
2534 Ptr = LD->getBasePtr();
2535 VT = LD->getMemoryVT();
2536 Alignment = LD->getAlignment();
2537 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
2538 Ptr = ST->getBasePtr();
2539 VT = ST->getMemoryVT();
2540 Alignment = ST->getAlignment();
2570 if (isa<FrameIndexSDNode>(Base) || isa<RegisterSDNode>(Base))
2573 SDValue Val = cast<StoreSDNode>(
N)->getValue();
2603 isa<ConstantSDNode>(Offset))
2618 unsigned &HiOpFlags,
unsigned &LoOpFlags,
2635 if (GV->hasHiddenVisibility()) {
2685 EVT PtrVT =
Op.getValueType();
2697 unsigned MOHiFlag, MOLoFlag;
2762 EVT PtrVT = Op.getValueType();
2773 unsigned MOHiFlag, MOLoFlag;
2790 EVT PtrVT =
Op.getValueType();
2804 unsigned MOHiFlag, MOLoFlag;
2825 bool is64bit = Subtarget.
isPPC64();
2853 PtrVT, GOTReg, TGA);
2855 if (!
TM.isPositionIndependent())
2863 PtrVT, TGA, GOTPtr);
2900 PtrVT, GOTPtr, TGA, TGA);
2902 PtrVT, TLSAddr, TGA);
2911 EVT PtrVT =
Op.getValueType();
2924 unsigned MOHiFlag, MOLoFlag;
2984 if (
C->isAllOnesValue() ||
C->isNullValue())
2993 EVT LHSVT =
Op.getOperand(0).getValueType();
2995 EVT VT =
Op.getValueType();
3005 EVT VT =
Node->getValueType(0);
3009 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3050 InChain = OverflowArea.
getValue(1);
3096 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3103 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3108 Op.getOperand(1),
Op.getOperand(2),
3115 return Op.getOperand(0);
3127 bool isPPC64 = (PtrVT ==
MVT::i64);
3133 Entry.Ty = IntPtrTy;
3146 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3150 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3151 return CallResult.second;
3165 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3166 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3201 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3204 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3207 uint64_t FPROffset = 1;
3210 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3216 uint64_t nextOffset = FPROffset;
3224 nextOffset += StackOffset;
3225 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3228 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3230 nextOffset += FrameOffset;
3231 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3234 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3240static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3241 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
3242 PPC::F11, PPC::F12, PPC::F13};
3246 PPC::QF1, PPC::QF2, PPC::QF3, PPC::QF4, PPC::QF5, PPC::QF6, PPC::QF7,
3247 PPC::QF8, PPC::QF9, PPC::QF10, PPC::QF11, PPC::QF12, PPC::QF13};
3252 unsigned PtrByteSize) {
3260 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3269 unsigned PtrByteSize) {
3270 unsigned Align = PtrByteSize;
3286 if (BVAlign > PtrByteSize) {
3287 if (BVAlign % PtrByteSize != 0)
3289 "ByVal alignment is not a multiple of the pointer size");
3315 unsigned PtrByteSize,
3316 unsigned LinkageSize,
3317 unsigned ParamAreaSize,
3318 unsigned &ArgOffset,
3319 unsigned &AvailableFPRs,
3320 unsigned &AvailableVRs,
bool HasQPX) {
3321 bool UseMemory =
false;
3326 ArgOffset = ((ArgOffset + Align - 1) / Align) * Align;
3329 if (ArgOffset >= LinkageSize + ParamAreaSize)
3335 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3338 if (ArgOffset > LinkageSize + ParamAreaSize)
3349 if (AvailableFPRs > 0) {
3357 if (AvailableVRs > 0) {
3369 unsigned NumBytes) {
3370 unsigned TargetAlign =
Lowering->getStackAlignment();
3371 unsigned AlignMask = TargetAlign - 1;
3372 NumBytes = (NumBytes + AlignMask) & ~AlignMask;
3376SDValue PPCTargetLowering::LowerFormalArguments(
3382 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins,
3385 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins,
3388 return LowerFormalArguments_Darwin(Chain, CallConv, isVarArg, Ins,
3393SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
3435 unsigned PtrByteSize = 4;
3444 CCInfo.AllocateStack(LinkageSize, PtrByteSize);
3446 CCInfo.PreAnalyzeFormalArguments(Ins);
3449 CCInfo.clearWasPPCF128();
3451 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
3464 RC = &PPC::GPRCRegClass;
3468 RC = &PPC::VSSRCRegClass;
3469 else if (Subtarget.
hasSPE())
3470 RC = &PPC::SPE4RCRegClass;
3472 RC = &PPC::F4RCRegClass;
3476 RC = &PPC::VSFRCRegClass;
3477 else if (Subtarget.
hasSPE())
3479 RC = &PPC::GPRCRegClass;
3481 RC = &PPC::F8RCRegClass;
3486 RC = &PPC::VRRCRegClass;
3489 RC = Subtarget.
hasQPX() ? &PPC::QSRCRegClass : &PPC::VRRCRegClass;
3493 RC = &PPC::VRRCRegClass;
3496 RC = &PPC::QFRCRegClass;
3499 RC = &PPC::QBRCRegClass;
3507 assert(i + 1 < e &&
"No second half of double precision argument");
3509 unsigned RegHi = MF.
addLiveIn(ArgLocs[++i].getLocReg(), RC);
3535 ArgOffset += ArgSize - ObjSize;
3553 CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrByteSize);
3558 unsigned MinReservedArea = CCByValInfo.getNextStackOffset();
3559 MinReservedArea = std::max(MinReservedArea, LinkageSize);
3575 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
3576 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
3581 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
3593 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
3598 CCInfo.getNextStackOffset(),
true));
3606 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
3610 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
3625 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
3629 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
3642 if (!MemOps.
empty())
3653 const SDLoc &dl)
const {
3664SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
3677 "fastcc not supported on varargs functions");
3683 unsigned PtrByteSize = 8;
3687 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
3688 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
3691 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
3692 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
3698 const unsigned Num_QFPR_Regs = Num_FPR_Regs;
3706 bool HasParameterArea = !isELFv2ABI || isVarArg;
3707 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
3708 unsigned NumBytes = LinkageSize;
3709 unsigned AvailableFPRs = Num_FPR_Regs;
3710 unsigned AvailableVRs = Num_VR_Regs;
3711 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
3712 if (Ins[i].Flags.
isNest())
3716 PtrByteSize, LinkageSize, ParamAreaSize,
3717 NumBytes, AvailableFPRs, AvailableVRs,
3719 HasParameterArea =
true;
3726 unsigned ArgOffset = LinkageSize;
3727 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
3728 unsigned &QFPR_idx = FPR_idx;
3731 unsigned CurArgIdx = 0;
3732 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
3734 bool needsLoad =
false;
3735 EVT ObjectVT =
Ins[ArgNo].VT;
3736 EVT OrigVT =
Ins[ArgNo].ArgVT;
3738 unsigned ArgSize = ObjSize;
3740 if (Ins[ArgNo].isOrigArg()) {
3741 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
3742 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
3747 unsigned CurArgOffset,
Align;
3748 auto ComputeArgOffset = [&]() {
3751 ArgOffset = ((ArgOffset +
Align - 1) / Align) *
Align;
3752 CurArgOffset = ArgOffset;
3759 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
3760 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
3766 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
3773 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3795 if (HasParameterArea ||
3796 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
3803 if (ObjSize < PtrByteSize) {
3807 if (!isLittleEndian) {
3813 if (GPR_idx != Num_GPR_Regs) {
3814 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
3819 if (ObjSize==1 || ObjSize==2 || ObjSize==4) {
3836 ArgOffset += PtrByteSize;
3845 for (
unsigned j = 0; j < ArgSize; j += PtrByteSize) {
3846 if (GPR_idx == Num_GPR_Regs)
3849 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
3862 ArgOffset += ArgSize;
3873 unsigned VReg = MF.
addLiveIn(PPC::X11, &PPC::G8RCRegClass);
3877 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
3885 if (GPR_idx != Num_GPR_Regs) {
3886 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
3893 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
3899 ArgSize = PtrByteSize;
3910 if (FPR_idx != Num_FPR_Regs) {
3916 ? &PPC::VSSRCRegClass
3917 : &PPC::F4RCRegClass);
3920 ? &PPC::VSFRCRegClass
3921 : &PPC::F8RCRegClass);
3932 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
3937 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
3956 ArgOffset += ArgSize;
3958 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3969 if (!Subtarget.
hasQPX()) {
3973 if (VR_idx != Num_VR_Regs) {
3974 unsigned VReg = MF.
addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
3988 "Invalid QPX parameter type");
3996 if (QFPR_idx != Num_QFPR_Regs) {
3999 case MVT::v4f64: RC = &PPC::QFRCRegClass;
break;
4000 case MVT::v4f32: RC = &PPC::QSRCRegClass;
break;
4001 default: RC = &PPC::QBRCRegClass;
break;
4020 if (ObjSize < ArgSize && !isLittleEndian)
4021 CurArgOffset += ArgSize - ObjSize;
4031 unsigned MinReservedArea;
4032 if (HasParameterArea)
4033 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4035 MinReservedArea = LinkageSize;
4048 int Depth = ArgOffset;
4057 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4058 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4059 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
4070 if (!MemOps.
empty())
4076SDValue PPCTargetLowering::LowerFormalArguments_Darwin(
4091 unsigned PtrByteSize = isPPC64 ? 8 : 4;
4093 unsigned ArgOffset = LinkageSize;
4095 unsigned MinReservedArea = ArgOffset;
4098 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4099 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4102 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4103 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4106 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4107 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4114 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4116 const MCPhysReg *GPR = isPPC64 ? GPR_64 : GPR_32;
4125 unsigned VecArgOffset = ArgOffset;
4126 if (!isVarArg && !isPPC64) {
4127 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e;
4129 EVT ObjectVT =
Ins[ArgNo].VT;
4136 ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4137 VecArgOffset += ArgSize;
4165 VecArgOffset = ((VecArgOffset+15)/16)*16;
4166 VecArgOffset += 12*16;
4173 unsigned nAltivecParamsAtEnd = 0;
4175 unsigned CurArgIdx = 0;
4176 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4178 bool needsLoad =
false;
4179 EVT ObjectVT =
Ins[ArgNo].VT;
4181 unsigned ArgSize = ObjSize;
4183 if (Ins[ArgNo].isOrigArg()) {
4184 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4185 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4187 unsigned CurArgOffset = ArgOffset;
4192 if (isVarArg || isPPC64) {
4193 MinReservedArea = ((MinReservedArea+15)/16)*16;
4197 }
else nAltivecParamsAtEnd++;
4207 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4211 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4214 if (ObjSize==1 || ObjSize==2) {
4215 CurArgOffset = CurArgOffset + (4 - ObjSize);
4221 if (ObjSize==1 || ObjSize==2) {
4222 if (GPR_idx != Num_GPR_Regs) {
4225 VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
4227 VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass);
4237 ArgOffset += PtrByteSize;
4241 for (
unsigned j = 0; j < ArgSize; j += PtrByteSize) {
4245 if (GPR_idx != Num_GPR_Regs) {
4248 VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
4250 VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass);
4258 ArgOffset += PtrByteSize;
4260 ArgOffset += ArgSize - (ArgOffset-CurArgOffset);
4272 if (GPR_idx != Num_GPR_Regs) {
4273 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass);
4282 ArgSize = PtrByteSize;
4285 ArgOffset += PtrByteSize;
4290 if (GPR_idx != Num_GPR_Regs) {
4291 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
4297 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4302 ArgSize = PtrByteSize;
4312 if (GPR_idx != Num_GPR_Regs) {
4314 if (ObjSize == 8 && GPR_idx != Num_GPR_Regs && !isPPC64)
4317 if (FPR_idx != Num_FPR_Regs) {
4332 ArgOffset += isPPC64 ? 8 : ObjSize;
4340 if (VR_idx != Num_VR_Regs) {
4341 unsigned VReg = MF.
addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
4344 while ((ArgOffset % 16) != 0) {
4345 ArgOffset += PtrByteSize;
4346 if (GPR_idx != Num_GPR_Regs)
4350 GPR_idx = std::min(GPR_idx+4, Num_GPR_Regs);
4354 if (!isVarArg && !isPPC64) {
4356 CurArgOffset = VecArgOffset;
4360 ArgOffset = ((ArgOffset+15)/16)*16;
4361 CurArgOffset = ArgOffset;
4373 CurArgOffset + (ArgSize - ObjSize),
4383 if (nAltivecParamsAtEnd) {
4384 MinReservedArea = ((MinReservedArea+15)/16)*16;
4385 MinReservedArea += 16*nAltivecParamsAtEnd;
4389 MinReservedArea = std::max(MinReservedArea, LinkageSize + 8 * PtrByteSize);
4402 int Depth = ArgOffset;
4412 for (; GPR_idx != Num_GPR_Regs; ++GPR_idx) {
4416 VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
4418 VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass);
4430 if (!MemOps.
empty())
4439 unsigned ParamSize) {
4441 if (!isTailCall)
return 0;
4445 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4447 if (SPDiff < FI->getTailCallSPDelta())
4473 return TM.shouldAssumeDSOLocal(*Caller->getParent(), GV);
4485 if (TM.getFunctionSections() || GV->
hasComdat() || Caller->hasComdat() ||
4488 if (
const auto *
F = dyn_cast<Function>(GV)) {
4489 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4510 if (!TM.shouldAssumeDSOLocal(*Caller->getParent(), GV))
4521 const unsigned PtrByteSize = 8;
4525 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4526 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4529 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4530 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4534 const unsigned NumFPRs = 13;
4536 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4538 unsigned NumBytes = LinkageSize;
4539 unsigned AvailableFPRs = NumFPRs;
4540 unsigned AvailableVRs = NumVRs;
4543 if (Param.Flags.isNest())
continue;
4546 PtrByteSize, LinkageSize, ParamAreaSize,
4547 NumBytes, AvailableFPRs, AvailableVRs,
4563 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4564 const Value* CalleeArg = *CalleeArgIter;
4565 const Value* CallerArg = &(*CallerArgIter);
4566 if (CalleeArg == CallerArg)
4574 isa<UndefValue>(CalleeArg))
4592 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4603PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4613 if (
DisableSCO && !TailCallOpt)
return false;
4616 if (isVarArg)
return false;
4648 if (
Caller.getCallingConv() != CalleeCC &&
4654 !isa<ExternalSymbolSDNode>(
Callee))
4684PPCTargetLowering::IsEligibleForTailCallOptimization(
SDValue Callee,
4700 for (
unsigned i = 0; i !=
Ins.size(); i++) {
4702 if (Flags.
isByVal())
return false;
4712 return G->getGlobal()->hasHiddenVisibility()
4713 ||
G->getGlobal()->hasProtectedVisibility();
4723 if (!
C)
return nullptr;
4725 int Addr =
C->getZExtValue();
4726 if ((Addr & 3) != 0 ||
4727 SignExtend32<26>(Addr) != Addr)
4732 (
int)
C->getZExtValue() >> 2,
SDLoc(Op),
4739struct TailCallArgumentInfo {
4744 TailCallArgumentInfo() =
default;
4754 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
4756 SDValue FIN = TailCallArgs[i].FrameIdxOp;
4757 int FI = TailCallArgs[i].FrameIdx;
4760 Chain, dl,
Arg, FIN,
4769 int SPDiff,
const SDLoc &dl) {
4775 bool isPPC64 = Subtarget.
isPPC64();
4776 int SlotSize = isPPC64 ? 8 : 4;
4777 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
4779 NewRetAddrLoc,
true);
4782 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
4788 int NewFPLoc = SPDiff + FL->getFramePointerSaveOffset();
4792 Chain = DAG.
getStore(Chain, dl, OldFP, NewFramePtrIdx,
4806 int Offset = ArgOffset + SPDiff;
4807 uint32_t OpSize = (
Arg.getValueSizeInBits() + 7) / 8;
4811 TailCallArgumentInfo
Info;
4813 Info.FrameIdxOp = FIN;
4821SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
4827 LROpOut = getReturnAddrFrameIndex(DAG);
4834 FPOpOut = getFramePointerFrameIndex(DAG);
4861 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
4884 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
4894 if (!MemOpChains2.
empty())
4914 return G->getGlobal()->getValueType()->isFunctionTy();
4922 SDValue CallSeqStart,
const SDLoc &dl,
int SPDiff,
bool isTailCall,
4923 bool isPatchPoint,
bool hasNest,
4927 bool isPPC64 = Subtarget.
isPPC64();
4930 bool isAIXABI = Subtarget.
isAIXABI();
4938 bool needIndirectCall =
true;
4939 if (!isSVR4ABI || !isPPC64)
4943 needIndirectCall =
false;
4952 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(
Callee))
4953 GV =
G->getGlobal();
4954 bool Local = TM.shouldAssumeDSOLocal(*
Mod, GV);
4955 bool UsePlt = !Local && Subtarget.
isTargetELF() && !isPPC64;
4965 unsigned OpFlags = 0;
4970 Callee.getValueType(), 0, OpFlags);
4971 needIndirectCall =
false;
4975 unsigned char OpFlags = 0;
4982 needIndirectCall =
false;
4992 needIndirectCall =
false;
4995 if (needIndirectCall) {
5000 if (isSVR4ABI && isPPC64 && !isELFv2ABI) {
5072 MTCTROps[0] = Chain;
5073 MTCTROps[1] = LoadFuncPtr;
5074 MTCTROps[2] = InFlag;
5088 if (isSVR4ABI && isPPC64 && !isELFv2ABI && !hasNest)
5106 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5108 RegsToPass[i].second.getValueType()));
5113 if ((isSVR4ABI && isPPC64) || isAIXABI) {
5127SDValue PPCTargetLowering::LowerCallResult(
5135 CCRetInfo.AnalyzeCallResult(
5141 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5150 Chain =
Lo.getValue(1);
5151 InFlag =
Lo.getValue(2);
5155 Chain =
Hi.getValue(1);
5156 InFlag =
Hi.getValue(2);
5191SDValue PPCTargetLowering::FinishCall(
5198 std::vector<EVT> NodeTys;
5201 SPDiff, isTailCall, isPatchPoint, hasNest,
5202 RegsToPass, Ops, NodeTys, CS, Subtarget);
5211 int BytesCalleePops =
5219 assert(Mask &&
"Missing call preserved mask for calling convention");
5228 cast<RegisterSDNode>(
Callee)->getReg() == PPC::CTR) ||
5231 isa<ConstantSDNode>(
Callee)) &&
5232 "Expecting an global address, external symbol, absolute value or register");
5250 if (!isTailCall && !isPatchPoint &&
5290 Twine(
G->getGlobal()->getName()));
5296 Chain = DAG.
getNode(CallOpc, dl, NodeTys, Ops);
5305 return LowerCallResult(Chain, InFlag, CallConv, isVarArg,
5306 Ins, dl, DAG, InVals);
5330 IsEligibleForTailCallOptimization_64SVR4(
Callee, CallConv, CS,
5331 isVarArg, Outs, Ins, DAG);
5333 isTailCall = IsEligibleForTailCallOptimization(
Callee, CallConv, isVarArg,
5341 "Callee should be an llvm::Function object.");
5344 cast<GlobalAddressSDNode>(
Callee)->getGlobal();
5345 const unsigned Width =
5346 80 - strlen(
"TCO caller: ") - strlen(
", callee linkage: 0, 0");
5347 dbgs() <<
"TCO caller: "
5356 "site marked musttail");
5366 return LowerCall_64SVR4(Chain,
Callee, CallConv, isVarArg,
5367 isTailCall, isPatchPoint, Outs, OutVals, Ins,
5368 dl, DAG, InVals, CS);
5371 return LowerCall_32SVR4(Chain,
Callee, CallConv, isVarArg,
5372 isTailCall, isPatchPoint, Outs, OutVals, Ins,
5373 dl, DAG, InVals, CS);
5376 return LowerCall_AIX(Chain,
Callee, CallConv, isVarArg,
5377 isTailCall, isPatchPoint, Outs, OutVals, Ins,
5378 dl, DAG, InVals, CS);
5380 return LowerCall_Darwin(Chain,
Callee, CallConv, isVarArg,
5381 isTailCall, isPatchPoint, Outs, OutVals, Ins,
5382 dl, DAG, InVals, CS);
5385SDValue PPCTargetLowering::LowerCall_32SVR4(
5387 bool isTailCall,
bool isPatchPoint,
5400 unsigned PtrByteSize = 4;
5425 CCInfo.PreAnalyzeCallOperands(Outs);
5431 unsigned NumArgs = Outs.
size();
5433 for (
unsigned i = 0; i != NumArgs; ++i) {
5434 MVT ArgVT = Outs[i].VT;
5438 if (Outs[i].IsFixed) {
5448 errs() <<
"Call operand #" << i <<
" has unhandled type "
5458 CCInfo.clearWasPPCF128();
5465 CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrByteSize);
5472 unsigned NumBytes = CCByValInfo.getNextStackOffset();
5486 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5497 bool seenFloatArg =
false;
5502 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5504 ++i, ++RealArgIdx) {
5514 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5537 Chain = CallSeqStart = NewCallSeqStart;
5563 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
5587 if (!MemOpChains.
empty())
5593 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
5595 RegsToPass[i].
second, InFlag);
5603 SDValue Ops[] = { Chain, InFlag };
5615 return FinishCall(CallConv, dl, isTailCall, isVarArg, isPatchPoint,
5617 RegsToPass, InFlag, Chain, CallSeqStart,
Callee, SPDiff,
5618 NumBytes, Ins, InVals, CS);
5623SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
5635 return NewCallSeqStart;
5638SDValue PPCTargetLowering::LowerCall_64SVR4(
5640 bool isTailCall,
bool isPatchPoint,
5648 unsigned NumOps = Outs.
size();
5649 bool hasNest =
false;
5650 bool IsSibCall =
false;
5653 unsigned PtrByteSize = 8;
5670 "fastcc not supported on varargs functions");
5677 unsigned NumBytes = LinkageSize;
5678 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
5679 unsigned &QFPR_idx = FPR_idx;
5682 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
5683 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
5686 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
5687 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
5693 const unsigned NumQFPRs = NumFPRs;
5699 bool HasParameterArea = !isELFv2ABI || isVarArg || CallConv ==
CallingConv::Fast;
5700 if (!HasParameterArea) {
5701 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5702 unsigned AvailableFPRs = NumFPRs;
5703 unsigned AvailableVRs = NumVRs;
5704 unsigned NumBytesTmp = NumBytes;
5705 for (
unsigned i = 0; i != NumOps; ++i) {
5706 if (Outs[i].Flags.
isNest())
continue;
5708 PtrByteSize, LinkageSize, ParamAreaSize,
5709 NumBytesTmp, AvailableFPRs, AvailableVRs,
5711 HasParameterArea =
true;
5717 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
5722 HasParameterArea =
false;
5725 for (
unsigned i = 0; i != NumOps; ++i) {
5727 EVT ArgVT = Outs[i].VT;
5728 EVT OrigVT = Outs[i].ArgVT;
5736 if (NumGPRsUsed > NumGPRs)
5737 HasParameterArea =
true;
5744 if (++NumGPRsUsed <= NumGPRs)
5754 if (++NumVRsUsed <= NumVRs)
5760 if (Subtarget.
hasQPX()) {
5761 if (++NumFPRsUsed <= NumFPRs)
5764 if (++NumVRsUsed <= NumVRs)
5772 if (++NumFPRsUsed <= NumFPRs)
5776 HasParameterArea =
true;
5783 NumBytes = ((NumBytes +
Align - 1) / Align) *
Align;
5787 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
5790 unsigned NumBytesActuallyUsed = NumBytes;
5800 if (HasParameterArea)
5801 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
5803 NumBytes = LinkageSize;
5831 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5842 unsigned ArgOffset = LinkageSize;
5848 for (
unsigned i = 0; i != NumOps; ++i) {
5851 EVT ArgVT = Outs[i].VT;
5852 EVT OrigVT = Outs[i].ArgVT;
5861 auto ComputePtrOff = [&]() {
5865 ArgOffset = ((ArgOffset +
Align - 1) / Align) *
Align;
5876 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
5877 GPR_idx = std::min(GPR_idx, NumGPRs);
5909 if (GPR_idx != NumGPRs) {
5913 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
5915 ArgOffset += PtrByteSize;
5920 if (GPR_idx == NumGPRs &&
Size < 8) {
5922 if (!isLittleEndian) {
5927 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
5930 ArgOffset += PtrByteSize;
5947 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, PtrOff,
5952 if (
Size < 8 && GPR_idx != NumGPRs) {
5962 if (!isLittleEndian) {
5966 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
5974 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
5977 ArgOffset += PtrByteSize;
5983 for (
unsigned j=0; j<
Size; j+=PtrByteSize) {
5986 if (GPR_idx != NumGPRs) {
5990 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
5991 ArgOffset += PtrByteSize;
5993 ArgOffset += ((
Size - j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6000 switch (
Arg.getSimpleValueType().SimpleTy) {
6015 if (GPR_idx != NumGPRs) {
6016 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++],
Arg));
6021 assert(HasParameterArea &&
6022 "Parameter area must exist to pass an argument in memory.");
6024 true, isTailCall,
false, MemOpChains,
6025 TailCallArguments, dl);
6027 ArgOffset += PtrByteSize;
6030 ArgOffset += PtrByteSize;
6043 bool NeedGPROrStack = isVarArg || FPR_idx == NumFPRs;
6044 bool NeededLoad =
false;
6047 if (FPR_idx != NumFPRs)
6051 if (!NeedGPROrStack)
6073 }
else if (ArgOffset % PtrByteSize != 0) {
6077 if (!isLittleEndian)
6085 if (!isLittleEndian)
6095 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6108 assert(HasParameterArea &&
6109 "Parameter area must exist to pass an argument in memory.");
6111 true, isTailCall,
false, MemOpChains,
6112 TailCallArguments, dl);
6123 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6135 if (!Subtarget.
hasQPX()) {
6145 assert(HasParameterArea &&
6146 "Parameter area must exist if we have a varargs call.");
6152 if (VR_idx != NumVRs) {
6156 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6159 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6160 if (GPR_idx == NumGPRs)
6167 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6173 if (VR_idx != NumVRs) {
6174 RegsToPass.
push_back(std::make_pair(VR[VR_idx++],
Arg));
6179 assert(HasParameterArea &&
6180 "Parameter area must exist to pass an argument in memory.");
6182 true, isTailCall,
true, MemOpChains,
6183 TailCallArguments, dl);
6194 "Invalid QPX parameter type");
6199 bool IsF32 =
Arg.getValueType().getSimpleVT().SimpleTy ==
MVT::v4f32;
6201 assert(HasParameterArea &&
6202 "Parameter area must exist if we have a varargs call.");
6208 if (QFPR_idx != NumQFPRs) {
6212 RegsToPass.
push_back(std::make_pair(
QFPR[QFPR_idx++], Load));
6214 ArgOffset += (IsF32 ? 16 : 32);
6215 for (
unsigned i = 0; i < (IsF32 ? 16U : 32U); i += PtrByteSize) {
6216 if (GPR_idx == NumGPRs)
6223 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6229 if (QFPR_idx != NumQFPRs) {
6235 assert(HasParameterArea &&
6236 "Parameter area must exist to pass an argument in memory.");
6238 true, isTailCall,
true, MemOpChains,
6239 TailCallArguments, dl);
6241 ArgOffset += (IsF32 ? 16 : 32);
6245 ArgOffset += (IsF32 ? 16 : 32);
6251 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6252 "mismatch in size of parameter area");
6253 (void)NumBytesActuallyUsed;
6255 if (!MemOpChains.
empty())
6261 if (!isTailCall && !isPatchPoint &&
6263 !isa<ExternalSymbolSDNode>(
Callee)) {
6277 if (isELFv2ABI && !isPatchPoint)
6284 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6286 RegsToPass[i].
second, InFlag);
6290 if (isTailCall && !IsSibCall)
6294 return FinishCall(CallConv, dl, isTailCall, isVarArg, isPatchPoint, hasNest,
6295 DAG, RegsToPass, InFlag, Chain, CallSeqStart,
Callee,
6296 SPDiff, NumBytes, Ins, InVals, CS);
6299SDValue PPCTargetLowering::LowerCall_Darwin(
6301 bool isTailCall,
bool isPatchPoint,
6307 unsigned NumOps = Outs.
size();
6311 unsigned PtrByteSize = isPPC64 ? 8 : 4;
6328 unsigned NumBytes = LinkageSize;
6336 unsigned nAltivecParamsAtEnd = 0;
6337 for (
unsigned i = 0; i != NumOps; ++i) {
6339 EVT ArgVT = Outs[i].VT;
6344 if (!isVarArg && !isPPC64) {
6347 nAltivecParamsAtEnd++;
6351 NumBytes = ((NumBytes+15)/16)*16;
6357 if (nAltivecParamsAtEnd) {
6358 NumBytes = ((NumBytes+15)/16)*16;
6359 NumBytes += 16*nAltivecParamsAtEnd;
6367 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6391 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6406 unsigned ArgOffset = LinkageSize;
6407 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6410 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6411 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
6414 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6415 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6418 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6419 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6422 const unsigned NumFPRs = 13;
6425 const MCPhysReg *GPR = isPPC64 ? GPR_64 : GPR_32;
6431 for (
unsigned i = 0; i != NumOps; ++i) {
6459 if (GPR_idx != NumGPRs) {
6463 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6465 ArgOffset += PtrByteSize;
6470 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6473 ArgOffset += PtrByteSize;
6480 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, PtrOff,
6487 for (
unsigned j=0; j<
Size; j+=PtrByteSize) {
6490 if (GPR_idx != NumGPRs) {
6494 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6495 ArgOffset += PtrByteSize;
6497 ArgOffset += ((
Size - j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6504 switch (
Arg.getSimpleValueType().SimpleTy) {
6509 if (GPR_idx != NumGPRs) {
6513 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++],
Arg));
6516 isPPC64, isTailCall,
false, MemOpChains,
6517 TailCallArguments, dl);
6519 ArgOffset += PtrByteSize;
6523 if (FPR_idx != NumFPRs) {
6532 if (GPR_idx != NumGPRs) {
6536 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6538 if (GPR_idx != NumGPRs &&
Arg.getValueType() ==
MVT::f64 && !isPPC64){
6544 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6550 if (GPR_idx != NumGPRs)
6552 if (GPR_idx != NumGPRs &&
Arg.getValueType() ==
MVT::f64 &&
6558 isPPC64, isTailCall,
false, MemOpChains,
6559 TailCallArguments, dl);
6563 ArgOffset +=
Arg.getValueType() ==
MVT::f32 ? 4 : 8;
6575 while (ArgOffset % 16 !=0) {
6576 ArgOffset += PtrByteSize;
6577 if (GPR_idx != NumGPRs)
6587 if (VR_idx != NumVRs) {
6591 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6594 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6595 if (GPR_idx == NumGPRs)
6602 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6609 if (VR_idx != NumVRs) {
6611 RegsToPass.
push_back(std::make_pair(VR[VR_idx++],
Arg));
6612 }
else if (nAltivecParamsAtEnd==0) {
6615 isPPC64, isTailCall,
true, MemOpChains,
6616 TailCallArguments, dl);
6627 if (!isVarArg && nAltivecParamsAtEnd > NumVRs) {
6630 ArgOffset = ((ArgOffset+15)/16)*16;
6632 for (
unsigned i = 0; i != NumOps; ++i) {
6634 EVT ArgType = Outs[i].VT;
6641 isPPC64, isTailCall,
true, MemOpChains,
6642 TailCallArguments, dl);
6649 if (!MemOpChains.
empty())
6657 !isa<ExternalSymbolSDNode>(
Callee) &&
6659 RegsToPass.
push_back(std::make_pair((
unsigned)(isPPC64 ? PPC::X12 :
6665 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6667 RegsToPass[i].
second, InFlag);
6675 return FinishCall(CallConv, dl, isTailCall, isVarArg, isPatchPoint,
6677 RegsToPass, InFlag, Chain, CallSeqStart,
Callee, SPDiff,
6678 NumBytes, Ins, InVals, CS);
6682SDValue PPCTargetLowering::LowerCall_AIX(
6684 bool isTailCall,
bool isPatchPoint,
6692 "Unimplemented calling convention!");
6693 if (isVarArg || isPatchPoint)
6698 unsigned PtrByteSize = isPPC64 ? 8 : 4;
6699 unsigned NumOps = Outs.
size();
6714 unsigned NumBytes = LinkageSize + 8 * PtrByteSize;
6723 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6724 PPC::R7, PPC::R8, PPC::R9, PPC::R10
6727 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6728 PPC::X7, PPC::X8, PPC::X9, PPC::X10
6733 const MCPhysReg *GPR = isPPC64 ? GPR_64 : GPR_32;
6734 unsigned GPR_idx = 0;
6742 for (
unsigned i = 0; i != NumOps; ++i) {
6758 switch (
Arg.getSimpleValueType().SimpleTy) {
6763 if (GPR_idx != NumGPRs)
6764 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++],
Arg));
6786 !isa<ExternalSymbolSDNode>(
Callee))
6792 for (
auto Reg : RegsToPass) {
6797 return FinishCall(CallConv, dl, isTailCall, isVarArg, isPatchPoint,
6799 RegsToPass, InFlag, Chain, CallSeqStart,
Callee, SPDiff,
6800 NumBytes, Ins, InVals, CS);
6809 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
6810 return CCInfo.CheckReturn(
6825 CCInfo.AnalyzeReturn(Outs,
6834 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
6880 else if (PPC::F8RCRegClass.
contains(*
I))
6882 else if (PPC::CRRCRegClass.
contains(*
I))
6884 else if (PPC::VRRCRegClass.
contains(*
I))
6895 RetOps.push_back(Flag);
6901PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
6906 EVT IntVT =
Op.getValueType();
6910 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
6912 SDValue Ops[2] = {Chain, FPSIdx};
6926 bool isPPC64 = Subtarget.
isPPC64();
6927 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
6947 bool isPPC64 = Subtarget.
isPPC64();
6968PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
6970 bool isPPC64 = Subtarget.
isPPC64();
7003 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7005 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
7014 bool isPPC64 = Subtarget.
isPPC64();
7026 Op.getOperand(0),
Op.getOperand(1));
7033 Op.getOperand(0),
Op.getOperand(1));
7037 if (
Op.getValueType().isVector())
7038 return LowerVectorLoad(Op, DAG);
7041 "Custom lowering only for i1 loads");
7062 if (
Op.getOperand(1).getValueType().isVector())
7063 return LowerVectorStore(Op, DAG);
7066 "Custom lowering only for i1 stores");
7086 "Custom lowering only for i1 results");
7115 assert(
Op.getValueType().isVector() &&
"Vector type expected.");
7120 assert(SrcSize <= 128 &&
"Source must fit in an Altivec/VSX vector");
7123 EVT TrgVT =
Op.getValueType();
7133 for (
unsigned i = 0; i < TrgNumElts; ++i)
7136 for (
unsigned i = 1; i <= TrgNumElts; ++i)
7140 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
7152 if (!
Op.getOperand(0).getValueType().isFloatingPoint() ||
7153 !
Op.getOperand(2).getValueType().isFloatingPoint())
7169 EVT ResVT =
Op.getValueType();
7170 EVT CmpVT =
Op.getOperand(0).getValueType();
7171 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
7172 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
7221 if (Cmp.getValueType() ==
MVT::f32)
7231 if (Cmp.getValueType() ==
MVT::f32)
7237 if (Cmp.getValueType() ==
MVT::f32)
7243 if (Cmp.getValueType() ==
MVT::f32)
7249 if (Cmp.getValueType() ==
MVT::f32)
7256void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
7258 const SDLoc &dl)
const {
7259 assert(
Op.getOperand(0).getValueType().isFloatingPoint());
7265 switch (
Op.getSimpleValueType().SimpleTy) {
7276 "i64 FP_TO_UINT is supported only with FPCVT");
7287 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
7305 if (
Op.getValueType() ==
MVT::i32 && !i32Stack) {
7321 const SDLoc &dl)
const {
7322 assert(
Op.getOperand(0).getValueType().isFloatingPoint());
7329 switch (
Op.getSimpleValueType().SimpleTy) {
7341 "i64 FP_TO_UINT is supported only with FPCVT");
7352 const SDLoc &dl)
const {
7377 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
7384 Op.getOperand(0), Tmp);
7390 return DAG.
getSelectCC(dl,
Op.getOperand(0), Tmp, True, False,
7399 return LowerFP_TO_INTDirectMove(Op, DAG, dl);
7402 LowerFP_TO_INTForReuse(Op, RLI, DAG, dl);
7404 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
7405 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
7416bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
7425 Op.getOperand(0).getValueType())) {
7427 LowerFP_TO_INTForReuse(Op, RLI, DAG, dl);
7432 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
7433 LD->isNonTemporal())
7435 if (
LD->getMemoryVT() != MemVT)
7438 RLI.Ptr =
LD->getBasePtr();
7439 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
7441 "Non-pre-inc AM on PPC?");
7446 RLI.Chain =
LD->getChain();
7447 RLI.MPI =
LD->getPointerInfo();
7448 RLI.IsDereferenceable =
LD->isDereferenceable();
7449 RLI.IsInvariant =
LD->isInvariant();
7450 RLI.Alignment =
LD->getAlignment();
7451 RLI.AAInfo =
LD->getAAInfo();
7452 RLI.Ranges =
LD->getRanges();
7454 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
7462void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
7468 SDLoc dl(NewResChain);
7473 "A new TF really is required here");
7482bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &Op)
const {
7483 SDNode *Origin =
Op.getOperand(0).getNode();
7498 if (UI.getUse().get().getResNo() != 0)
7514 const SDLoc &dl)
const {
7517 "Invalid floating point type as target of conversion");
7519 "Int to FP conversions with direct moves require FPCVT");
7522 bool SinglePrec =
Op.getValueType() ==
MVT::f32;
7555 for (
unsigned i = 1; i < NumConcat; ++i)
7562 const SDLoc &dl)
const {
7564 unsigned Opc =
Op.getOpcode();
7566 "Unexpected conversion type");
7568 "Supports conversions to v2f64/v4f32 only.");
7579 for (
unsigned i = 0; i < WideNumElts; ++i)
7582 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
7583 int SaveElts = FourEltRes ? 4 : 2;
7585 for (
int i = 0; i < SaveElts; i++)
7586 ShuffV[i * Stride] = i;
7588 for (
int i = 1; i <= SaveElts; i++)
7589 ShuffV[i * Stride - 1] = i - 1;
7599 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
7603 Extend = DAG.
getNode(ExtendOp, dl, IntermediateVT, Arrange);
7605 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
7612 EVT InVT =
Op.getOperand(0).getValueType();
7613 EVT OutVT =
Op.getValueType();
7616 return LowerINT_TO_FPVector(Op, DAG, dl);
7647 if (
Op.getOperand(0).getValueType() ==
MVT::i1)
7654 if (Subtarget.
hasDirectMove() && directMoveIsProfitable(Op) &&
7656 return LowerINT_TO_FPDirectMove(Op, DAG, dl);
7659 "UINT_TO_FP is supported only with FPCVT");
7672 if (
Op.getOperand(0).getValueType() ==
MVT::i64) {
7724 if (canReuseLoadAddress(SINT,
MVT::i64, RLI, DAG)) {
7726 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
7727 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
7732 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
7733 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
7737 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
7742 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
7743 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
7747 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
7765 "Expected an i32 store");
7775 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
7776 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
7793 "Unhandled INT_TO_FP type in custom expander!");
7806 if (!(ReusingLoad = canReuseLoadAddress(
Op.getOperand(0),
MVT::i32, RLI,
7817 "Expected an i32 store");
7828 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
7829 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
7835 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
7838 "i32->FP without LFIWAX supported only on PPC64");
7888 EVT VT =
Op.getValueType();
7929 EVT VT =
Op.getValueType();
7933 VT ==
Op.getOperand(1).getValueType() &&
7953 SDValue OutOps[] = { OutLo, OutHi };
7958 EVT VT =
Op.getValueType();
7962 VT ==
Op.getOperand(1).getValueType() &&
7982 SDValue OutOps[] = { OutLo, OutHi };
7988 EVT VT =
Op.getValueType();
7991 VT ==
Op.getOperand(1).getValueType() &&
8011 SDValue OutOps[] = { OutLo, OutHi };
8023 assert(Val >= -16 && Val <= 15 &&
"vsplti is out of range!");
8025 static const MVT VTys[] = {
8035 EVT CanonicalVT = VTys[SplatSize-1];
8045 if (DestVT ==
MVT::Other) DestVT = Op.getValueType();
8079 for (
unsigned i = 0; i != 16; ++i)
8107 bool IsSplat =
true;
8108 bool IsLoad =
false;
8135 return !(IsSplat && IsLoad);
8164 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
8178 "BUILD_VECTOR for v4i1 does not have 4 operands");
8181 for (
unsigned i = 0; i < 4; ++i) {
8183 if (!isa<ConstantSDNode>(BVN->
getOperand(i))) {
8196 for (
unsigned i = 0; i < 4; ++i) {
8217 for (
unsigned i = 0; i < 4; ++i) {
8225 if (StoreSize > 4) {
8240 if (!Stores.
empty())
8271 APInt APSplatBits, APSplatUndef;
8272 unsigned SplatBitSize;
8276 SplatBitSize > 32) {
8280 if (Subtarget.
hasVSX() &&
8289 unsigned SplatSize = SplatBitSize / 8;
8294 if (SplatBits == 0) {
8329 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
8331 if (SextVal >= -16 && SextVal <= 15)
8332 return BuildSplatI(SextVal, SplatSize,
Op.getValueType(), DAG, dl);
8343 if (SextVal >= -32 && SextVal <= 31) {
8352 if (VT ==
Op.getValueType())
8361 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
8375 static const signed char SplatCsts[] = {
8376 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
8377 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
8383 int i = SplatCsts[idx];
8387 unsigned TypeShiftAmt = i & (SplatBitSize-1);
8390 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
8392 static const unsigned IIDs[] = {
8393 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
8394 Intrinsic::ppc_altivec_vslw
8401 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
8403 static const unsigned IIDs[] = {
8404 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
8405 Intrinsic::ppc_altivec_vsrw
8412 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
8414 static const unsigned IIDs[] = {
8415 Intrinsic::ppc_altivec_vsrab, Intrinsic::ppc_altivec_vsrah, 0,
8416 Intrinsic::ppc_altivec_vsraw
8423 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
8424 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
8426 static const unsigned IIDs[] = {
8427 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
8428 Intrinsic::ppc_altivec_vrlw
8435 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
8441 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
8447 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
8462 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8463 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8464 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8480 if (LHSID == (1*9+2)*9+3)
return LHS;
8481 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
8493 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
8494 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
8495 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
8496 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
8499 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
8500 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
8501 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
8502 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
8505 for (
unsigned i = 0; i != 16; ++i)
8506 ShufIdxs[i] = (i&3)+0;
8509 for (
unsigned i = 0; i != 16; ++i)
8510 ShufIdxs[i] = (i&3)+4;
8513 for (
unsigned i = 0; i != 16; ++i)
8514 ShufIdxs[i] = (i&3)+8;
8517 for (
unsigned i = 0; i != 16; ++i)
8518 ShufIdxs[i] = (i&3)+12;
8539 const unsigned BytesInVector = 16;
8544 unsigned ShiftElts = 0, InsertAtByte = 0;
8548 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
8549 0, 15, 14, 13, 12, 11, 10, 9};
8550 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
8551 1, 2, 3, 4, 5, 6, 7, 8};
8554 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
8566 bool FoundCandidate =
false;
8570 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
8573 for (
unsigned i = 0; i < BytesInVector; ++i) {
8574 unsigned CurrentElement =
Mask[i];
8577 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
8580 bool OtherElementsInOrder =
true;
8583 for (
unsigned j = 0; j < BytesInVector; ++j) {
8590 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
8591 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
8592 OtherElementsInOrder =
false;
8599 if (OtherElementsInOrder) {
8606 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
8607 : BigEndianShifts[CurrentElement & 0xF];
8608 Swap = CurrentElement < BytesInVector;
8610 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
8611 FoundCandidate =
true;
8616 if (!FoundCandidate)
8640 const unsigned NumHalfWords = 8;
8641 const unsigned BytesInVector = NumHalfWords * 2;
8650 unsigned ShiftElts = 0, InsertAtByte = 0;
8654 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
8655 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
8658 uint32_t OriginalOrderLow = 0x1234567;
8659 uint32_t OriginalOrderHigh = 0x89ABCDEF;
8662 for (
unsigned i = 0; i < NumHalfWords; ++i) {
8663 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
8664 Mask |= ((
uint32_t)(
N->getMaskElt(i * 2) / 2) << MaskShift);
8680 bool FoundCandidate =
false;
8683 for (
unsigned i = 0; i < NumHalfWords; ++i) {
8684 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
8686 uint32_t MaskOtherElts = ~(0xF << MaskShift);
8694 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
8695 TargetOrder = OriginalOrderLow;
8699 if (MaskOneElt == VINSERTHSrcElem &&
8700 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
8701 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
8702 FoundCandidate =
true;
8708 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
8710 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
8712 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
8713 : BigEndianShifts[MaskOneElt & 0x7];
8714 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
8715 Swap = MaskOneElt < NumHalfWords;
8716 FoundCandidate =
true;
8722 if (!FoundCandidate)
8757 EVT VT =
Op.getValueType();
8760 unsigned ShiftElts, InsertAtByte;
8783 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
8786 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
8790 if (Subtarget.
hasVSX() &&
8803 if (Subtarget.
hasVSX() &&
8836 if (Subtarget.
hasVSX()) {
8854 if (Subtarget.
hasQPX()) {
8858 if (
V2.isUndef())
V2 = V1;
8861 if (AlignIdx != -1) {
8866 if (SplatIdx >= 4) {
8879 for (
unsigned i = 0; i < 4; ++i) {
8881 unsigned mm = m >= 0 ? (
unsigned) m : i;
8882 idx |= mm << (3-i)*3;
8917 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
8937 unsigned PFIndexes[4];
8938 bool isFourElementShuffle =
true;
8939 for (
unsigned i = 0; i != 4 && isFourElementShuffle; ++i) {
8941 for (
unsigned j = 0; j != 4; ++j) {
8942 if (PermMask[i*4+j] < 0)
8945 unsigned ByteSource = PermMask[i*4+j];
8946 if ((ByteSource & 3) != j) {
8947 isFourElementShuffle =
false;
8952 EltNo = ByteSource/4;
8953 }
else if (EltNo != ByteSource/4) {
8954 isFourElementShuffle =
false;
8958 PFIndexes[i] = EltNo;
8966 if (isFourElementShuffle && !isLittleEndian) {
8968 unsigned PFTableIndex =
8969 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8972 unsigned Cost = (PFEntry >> 30);
8991 if (
V2.isUndef())
V2 = V1;
9005 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
9007 for (
unsigned j = 0; j != BytesPerElement; ++j)
9030 unsigned IntrinsicID =
9031 cast<ConstantSDNode>(Intrin.
getOperand(0))->getZExtValue();
9034 switch (IntrinsicID) {
9038 case Intrinsic::ppc_altivec_vcmpbfp_p:
9042 case Intrinsic::ppc_altivec_vcmpeqfp_p:
9046 case Intrinsic::ppc_altivec_vcmpequb_p:
9050 case Intrinsic::ppc_altivec_vcmpequh_p:
9054 case Intrinsic::ppc_altivec_vcmpequw_p:
9058 case Intrinsic::ppc_altivec_vcmpequd_p:
9065 case Intrinsic::ppc_altivec_vcmpneb_p:
9066 case Intrinsic::ppc_altivec_vcmpneh_p:
9067 case Intrinsic::ppc_altivec_vcmpnew_p:
9068 case Intrinsic::ppc_altivec_vcmpnezb_p:
9069 case Intrinsic::ppc_altivec_vcmpnezh_p:
9070 case Intrinsic::ppc_altivec_vcmpnezw_p:
9072 switch (IntrinsicID) {
9075 case Intrinsic::ppc_altivec_vcmpneb_p:
9078 case Intrinsic::ppc_altivec_vcmpneh_p:
9081 case Intrinsic::ppc_altivec_vcmpnew_p:
9084 case Intrinsic::ppc_altivec_vcmpnezb_p:
9087 case Intrinsic::ppc_altivec_vcmpnezh_p:
9090 case Intrinsic::ppc_altivec_vcmpnezw_p:
9098 case Intrinsic::ppc_altivec_vcmpgefp_p:
9102 case Intrinsic::ppc_altivec_vcmpgtfp_p:
9106 case Intrinsic::ppc_altivec_vcmpgtsb_p:
9110 case Intrinsic::ppc_altivec_vcmpgtsh_p:
9114 case Intrinsic::ppc_altivec_vcmpgtsw_p:
9118 case Intrinsic::ppc_altivec_vcmpgtsd_p:
9125 case Intrinsic::ppc_altivec_vcmpgtub_p:
9129 case Intrinsic::ppc_altivec_vcmpgtuh_p:
9133 case Intrinsic::ppc_altivec_vcmpgtuw_p:
9137 case Intrinsic::ppc_altivec_vcmpgtud_p:
9146 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
9147 case Intrinsic::ppc_vsx_xvcmpgedp_p:
9148 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
9149 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
9150 case Intrinsic::ppc_vsx_xvcmpgesp_p:
9151 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
9152 if (Subtarget.
hasVSX()) {
9153 switch (IntrinsicID) {
9154 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
9157 case Intrinsic::ppc_vsx_xvcmpgedp_p:
9160 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
9163 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
9166 case Intrinsic::ppc_vsx_xvcmpgesp_p:
9169 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
9179 case Intrinsic::ppc_altivec_vcmpbfp:
9182 case Intrinsic::ppc_altivec_vcmpeqfp:
9185 case Intrinsic::ppc_altivec_vcmpequb:
9188 case Intrinsic::ppc_altivec_vcmpequh:
9191 case Intrinsic::ppc_altivec_vcmpequw:
9194 case Intrinsic::ppc_altivec_vcmpequd:
9200 case Intrinsic::ppc_altivec_vcmpneb:
9201 case Intrinsic::ppc_altivec_vcmpneh:
9202 case Intrinsic::ppc_altivec_vcmpnew:
9203 case Intrinsic::ppc_altivec_vcmpnezb:
9204 case Intrinsic::ppc_altivec_vcmpnezh:
9205 case Intrinsic::ppc_altivec_vcmpnezw:
9207 switch (IntrinsicID) {
9210 case Intrinsic::ppc_altivec_vcmpneb:
9213 case Intrinsic::ppc_altivec_vcmpneh:
9216 case Intrinsic::ppc_altivec_vcmpnew:
9219 case Intrinsic::ppc_altivec_vcmpnezb:
9222 case Intrinsic::ppc_altivec_vcmpnezh:
9225 case Intrinsic::ppc_altivec_vcmpnezw:
9232 case Intrinsic::ppc_altivec_vcmpgefp:
9235 case Intrinsic::ppc_altivec_vcmpgtfp:
9238 case Intrinsic::ppc_altivec_vcmpgtsb:
9241 case Intrinsic::ppc_altivec_vcmpgtsh:
9244 case Intrinsic::ppc_altivec_vcmpgtsw:
9247 case Intrinsic::ppc_altivec_vcmpgtsd:
9253 case Intrinsic::ppc_altivec_vcmpgtub:
9256 case Intrinsic::ppc_altivec_vcmpgtuh:
9259 case Intrinsic::ppc_altivec_vcmpgtuw:
9262 case Intrinsic::ppc_altivec_vcmpgtud:
9276 unsigned IntrinsicID =
9277 cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
9281 if (IntrinsicID == Intrinsic::thread_pointer) {
9298 Op.getOperand(1),
Op.getOperand(2),
9321 switch (cast<ConstantSDNode>(
Op.getOperand(1))->getZExtValue()) {
9324 BitNo = 0; InvertBit =
false;
9327 BitNo = 0; InvertBit =
true;
9330 BitNo = 2; InvertBit =
false;
9333 BitNo = 2; InvertBit =
true;
9355 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
9357 switch (cast<ConstantSDNode>(
Op.getOperand(ArgStart))->getZExtValue()) {
9358 case Intrinsic::ppc_cfence: {
9359 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
9360 assert(Subtarget.
isPPC64() &&
"Only 64-bit is supported for now.");
9363 Op.getOperand(ArgStart + 1)),
9375 for (
auto UI :
Op.getOperand(1)->uses()) {
9378 if (UI->getOperand(0) ==
Op.getOperand(0) &&
9379 UI->getOperand(1) ==
Op.getOperand(1))
9394 int VectorIndex = 0;
9407 "Expecting an atomic compare-and-swap here.");
9409 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
9410 EVT MemVT = AtomicNode->getMemoryVT();
9428 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
9429 Ops.
push_back(AtomicNode->getOperand(i));
9457 "Should only be called for ISD::INSERT_VECTOR_ELT");
9464 EVT VT =
Op.getValueType();
9472 unsigned InsertAtElement =
C->getZExtValue();
9473 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
9475 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
9489 "Unknown extract_vector_elt type");
9529 unsigned Offset = 4*cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue();
9559 EVT ScalarVT =
Op.getValueType().getScalarType(),
9563 SDValue Vals[4], LoadChains[4];
9564 for (
unsigned Idx = 0;
Idx < 4; ++
Idx) {
9566 if (ScalarVT != ScalarMemVT)
9573 Load = DAG.
getLoad(ScalarVT, dl, LoadChain, BasePtr,
9580 "Unknown addressing mode on vector load");
9586 LoadChains[
Idx] =
Load.getValue(1);
9611 SDValue VectElmts[4], VectElmtChains[4];
9612 for (
unsigned i = 0; i < 4; ++i) {
9620 VectElmtChains[i] = VectElmts[i].
getValue(1);
9648 EVT ScalarVT =
Value.getValueType().getScalarType(),
9653 for (
unsigned Idx = 0;
Idx < 4; ++
Idx) {
9658 if (ScalarVT != ScalarMemVT)
9672 "Unknown addressing mode on vector store");
9728 SDValue Loads[4], LoadChains[4];
9729 for (
unsigned i = 0; i < 4; ++i) {
9736 LoadChains[i] = Loads[i].
getValue(1);
9742 for (
unsigned i = 0; i < 4; ++i) {
9760 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
9785 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
9790 LHS, RHS, Zero, DAG, dl);
9792 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
9810 for (
unsigned i = 0; i != 8; ++i) {
9811 if (isLittleEndian) {
9813 Ops[i*2+1] = 2*i+16;
9816 Ops[i*2+1] = 2*i+1+16;
9830 assert(
Op.getOpcode() ==
ISD::ABS &&
"Should only be called for ISD::ABS");
9832 EVT VT =
Op.getValueType();
9834 "Only set vector abs as custom, scalar abs shouldn't reach here!");
9837 "Unexpected vector element type!");
9839 "Current subtarget doesn't support smax v2i64!");
9857 BifID = Intrinsic::ppc_altivec_vmaxsd;
9859 BifID = Intrinsic::ppc_altivec_vmaxsh;
9861 BifID = Intrinsic::ppc_altivec_vmaxsb;
9870 "Should only be called for ISD::FP_EXTEND");
9894 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr() };
9898 LoadOps,
LD->getMemoryVT(),
9899 LD->getMemOperand());
9902 NewLoad[0], NewLoad[1],
9908 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr() };
9912 LoadOps,
LD->getMemoryVT(),
LD->getMemOperand());
9922 switch (Op.getOpcode()) {
9941 return LowerGET_DYNAMIC_AREA_OFFSET(Op, DAG);
9948 case ISD::LOAD:
return LowerLOAD(Op, DAG);
9970 case ISD::MUL:
return LowerMUL(Op, DAG);
9971 case ISD::ABS:
return LowerABS(Op, DAG);
9984 return LowerINTRINSIC_VOID(Op, DAG);
9987 return LowerREM(Op, DAG);
9989 return LowerBSWAP(Op, DAG);
9991 return LowerATOMIC_CMP_SWAP(Op, DAG);
9999 switch (
N->getOpcode()) {
10001 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
10012 if (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue() !=
10013 Intrinsic::loop_decrement)
10017 "Unexpected result type for CTR decrement intrinsic");
10019 N->getValueType(0));
10032 EVT VT =
N->getValueType(0);
10050 EVT TrgVT =
N->getValueType(0);
10053 N->getOperand(0).getValueType().getSizeInBits() <= 128)
10092 if (isa<LoadInst>(Inst) && Subtarget.
isPPC64())
10096 Intrinsic::ppc_cfence, {Inst->getType()}),
10106 unsigned AtomicSize,
10107 unsigned BinOpcode,
10108 unsigned CmpOpcode,
10109 unsigned CmpPred)
const {
10113 auto LoadMnemonic = PPC::LDARX;
10114 auto StoreMnemonic = PPC::STDCX;
10115 switch (AtomicSize) {
10119 LoadMnemonic = PPC::LBARX;
10120 StoreMnemonic = PPC::STBCX;
10124 LoadMnemonic = PPC::LHARX;
10125 StoreMnemonic = PPC::STHCX;
10129 LoadMnemonic = PPC::LWARX;
10130 StoreMnemonic = PPC::STWCX;
10133 LoadMnemonic = PPC::LDARX;
10134 StoreMnemonic = PPC::STDCX;
10150 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
10152 F->insert(It, loopMBB);
10154 F->insert(It, loop2MBB);
10155 F->insert(It, exitMBB);
10161 Register TmpReg = (!BinOpcode) ? incr :
10163 : &PPC::GPRCRegClass);
10188 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
10194 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
10196 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
10198 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
10201 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
10226 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
10238 bool is64bit = Subtarget.
isPPC64();
10240 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
10246 unsigned dest =
MI.getOperand(0).getReg();
10247 unsigned ptrA =
MI.getOperand(1).getReg();
10248 unsigned ptrB =
MI.getOperand(2).getReg();
10249 unsigned incr =
MI.getOperand(3).getReg();
10254 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
10256 F->insert(It, loopMBB);
10258 F->insert(It, loop2MBB);
10259 F->insert(It, exitMBB);
10266 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
10309 if (ptrA != ZeroReg) {
10311 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
10319 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
10320 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
10323 .
addImm(is8bit ? 28 : 27);
10324 if (!isLittleEndian)
10325 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
10327 .
addImm(is8bit ? 24 : 16);
10329 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
10334 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
10344 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
10348 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
10353 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
10357 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
10360 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
10371 unsigned ValueReg = SReg;
10372 unsigned CmpReg = Incr2Reg;
10373 if (CmpOpcode == PPC::CMPW) {
10375 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
10379 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
10381 ValueReg = ValueSReg;
10384 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
10429 unsigned DstReg =
MI.getOperand(0).getReg();
10432 unsigned mainDstReg =
MRI.createVirtualRegister(RC);
10433 unsigned restoreDstReg =
MRI.createVirtualRegister(RC);
10437 "Invalid Pointer Size!");
10485 unsigned LabelReg =
MRI.createVirtualRegister(PtrRC);
10486 unsigned BufReg =
MI.getOperand(1).getReg();
10501 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
10503 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
10506 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
10518 MIB =
BuildMI(*thisMBB,
MI, DL,
TII->get(PPC::EH_SjLj_Setup))
10529 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
10533 MIB =
BuildMI(mainMBB, DL,
TII->get(PPC::STD))
10538 MIB =
BuildMI(mainMBB, DL,
TII->get(PPC::STW))
10550 TII->get(PPC::PHI), DstReg)
10554 MI.eraseFromParent();
10569 "Invalid Pointer Size!");
10572 (PVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
10573 unsigned Tmp =
MRI.createVirtualRegister(RC);
10575 unsigned FP = (PVT ==
MVT::i64) ? PPC::X31 : PPC::R31;
10576 unsigned SP = (PVT ==
MVT::i64) ? PPC::X1 : PPC::R1;
10590 unsigned BufReg =
MI.getOperand(0).getReg();
10645 MIB =
BuildMI(*MBB,
MI, DL,
TII->get(PPC::LD), PPC::X2)
10656 MI.eraseFromParent();
10663 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
10664 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
10666 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
10678 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
10679 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
10681 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
10682 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
10695 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
10696 MI.getOpcode() == PPC::SELECT_CC_I8 ||
MI.getOpcode() == PPC::SELECT_I4 ||
10697 MI.getOpcode() == PPC::SELECT_I8) {
10699 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
10700 MI.getOpcode() == PPC::SELECT_CC_I8)
10701 Cond.push_back(
MI.getOperand(4));
10704 Cond.push_back(
MI.getOperand(1));
10707 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(), Cond,
10708 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
10709 }
else if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
10710 MI.getOpcode() == PPC::SELECT_CC_I8 ||
10711 MI.getOpcode() == PPC::SELECT_CC_F4 ||
10712 MI.getOpcode() == PPC::SELECT_CC_F8 ||
10713 MI.getOpcode() == PPC::SELECT_CC_F16 ||
10714 MI.getOpcode() == PPC::SELECT_CC_QFRC ||
10715 MI.getOpcode() == PPC::SELECT_CC_QSRC ||
10716 MI.getOpcode() == PPC::SELECT_CC_QBRC ||
10717 MI.getOpcode() == PPC::SELECT_CC_VRRC ||
10718 MI.getOpcode() == PPC::SELECT_CC_VSFRC ||
10719 MI.getOpcode() == PPC::SELECT_CC_VSSRC ||
10720 MI.getOpcode() == PPC::SELECT_CC_VSRC ||
10721 MI.getOpcode() == PPC::SELECT_CC_SPE4 ||
10722 MI.getOpcode() == PPC::SELECT_CC_SPE ||
10723 MI.getOpcode() == PPC::SELECT_I4 ||
10724 MI.getOpcode() == PPC::SELECT_I8 ||
10725 MI.getOpcode() == PPC::SELECT_F4 ||
10726 MI.getOpcode() == PPC::SELECT_F8 ||
10727 MI.getOpcode() == PPC::SELECT_F16 ||
10728 MI.getOpcode() == PPC::SELECT_QFRC ||
10729 MI.getOpcode() == PPC::SELECT_QSRC ||
10730 MI.getOpcode() == PPC::SELECT_QBRC ||
10731 MI.getOpcode() == PPC::SELECT_SPE ||
10732 MI.getOpcode() == PPC::SELECT_SPE4 ||
10733 MI.getOpcode() == PPC::SELECT_VRRC ||
10734 MI.getOpcode() == PPC::SELECT_VSFRC ||
10735 MI.getOpcode() == PPC::SELECT_VSSRC ||
10736 MI.getOpcode() == PPC::SELECT_VSRC) {
10751 F->insert(It, copy0MBB);
10752 F->insert(It, sinkMBB);
10763 if (
MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8 ||
10764 MI.getOpcode() == PPC::SELECT_F4 ||
MI.getOpcode() == PPC::SELECT_F8 ||
10765 MI.getOpcode() == PPC::SELECT_F16 ||
10766 MI.getOpcode() == PPC::SELECT_SPE4 ||
10767 MI.getOpcode() == PPC::SELECT_SPE ||
10768 MI.getOpcode() == PPC::SELECT_QFRC ||
10769 MI.getOpcode() == PPC::SELECT_QSRC ||
10770 MI.getOpcode() == PPC::SELECT_QBRC ||
10771 MI.getOpcode() == PPC::SELECT_VRRC ||
10772 MI.getOpcode() == PPC::SELECT_VSFRC ||
10773 MI.getOpcode() == PPC::SELECT_VSSRC ||
10774 MI.getOpcode() == PPC::SELECT_VSRC) {
10776 .
addReg(
MI.getOperand(1).getReg())
10779 unsigned SelectPred =
MI.getOperand(4).getImm();
10782 .
addReg(
MI.getOperand(1).getReg())
10799 .
addReg(
MI.getOperand(3).getReg())
10801 .
addReg(
MI.getOperand(2).getReg())
10803 }
else if (
MI.getOpcode() == PPC::ReadTB) {
10819 F->insert(It, readMBB);
10820 F->insert(It, sinkMBB);
10832 unsigned LoReg =
MI.getOperand(0).getReg();
10833 unsigned HiReg =
MI.getOperand(1).getReg();
10841 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
10851 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
10853 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
10855 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
10857 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
10860 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
10862 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
10864 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
10866 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
10869 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
10871 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
10873 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
10875 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
10878 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
10880 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
10882 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
10884 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
10887 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
10889 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
10891 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
10893 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
10896 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
10898 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
10900 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
10902 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
10905 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
10907 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
10909 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
10911 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
10914 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
10916 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
10918 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
10920 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
10923 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
10925 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
10927 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
10929 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
10932 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
10934 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
10936 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
10938 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
10941 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
10943 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
10945 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
10947 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
10949 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
10950 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
10952 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
10954 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
10955 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
10957 auto LoadMnemonic = PPC::LDARX;
10958 auto StoreMnemonic = PPC::STDCX;
10959 switch (
MI.getOpcode()) {
10962 case PPC::ATOMIC_CMP_SWAP_I8:
10963 LoadMnemonic = PPC::LBARX;
10964 StoreMnemonic = PPC::STBCX;
10967 case PPC::ATOMIC_CMP_SWAP_I16:
10968 LoadMnemonic = PPC::LHARX;
10969 StoreMnemonic = PPC::STHCX;
10972 case PPC::ATOMIC_CMP_SWAP_I32:
10973 LoadMnemonic = PPC::LWARX;
10974 StoreMnemonic = PPC::STWCX;
10976 case PPC::ATOMIC_CMP_SWAP_I64:
10977 LoadMnemonic = PPC::LDARX;
10978 StoreMnemonic = PPC::STDCX;
10981 unsigned dest =
MI.getOperand(0).getReg();
10982 unsigned ptrA =
MI.getOperand(1).getReg();
10983 unsigned ptrB =
MI.getOperand(2).getReg();
10984 unsigned oldval =
MI.getOperand(3).getReg();
10985 unsigned newval =
MI.getOperand(4).getReg();
10992 F->insert(It, loop1MBB);
10993 F->insert(It, loop2MBB);
10994 F->insert(It, midMBB);
10995 F->insert(It, exitMBB);
11018 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), PPC::CR0)
11051 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
11052 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
11056 bool is64bit = Subtarget.
isPPC64();
11058 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
11060 unsigned dest =
MI.getOperand(0).getReg();
11061 unsigned ptrA =
MI.getOperand(1).getReg();
11062 unsigned ptrB =
MI.getOperand(2).getReg();
11063 unsigned oldval =
MI.getOperand(3).getReg();
11064 unsigned newval =
MI.getOperand(4).getReg();
11071 F->insert(It, loop1MBB);
11072 F->insert(It, loop2MBB);
11073 F->insert(It, midMBB);
11074 F->insert(It, exitMBB);
11081 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
11100 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
11133 if (ptrA != ZeroReg) {
11135 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
11144 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
11145 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
11148 .
addImm(is8bit ? 28 : 27);
11149 if (!isLittleEndian)
11150 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
11152 .
addImm(is8bit ? 24 : 16);
11154 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
11159 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
11164 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
11167 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
11174 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
11178 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
11181 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
11184 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
11189 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
11195 BuildMI(BB, dl,
TII->get(PPC::CMPW), PPC::CR0)
11206 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
11237 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
11241 unsigned Dest =
MI.getOperand(0).getReg();
11242 unsigned Src1 =
MI.getOperand(1).getReg();
11243 unsigned Src2 =
MI.getOperand(2).getReg();
11261 }
else if (
MI.getOpcode() == PPC::ANDIo_1_EQ_BIT ||
11262 MI.getOpcode() == PPC::ANDIo_1_GT_BIT ||
11263 MI.getOpcode() == PPC::ANDIo_1_EQ_BIT8 ||
11264 MI.getOpcode() == PPC::ANDIo_1_GT_BIT8) {
11265 unsigned Opcode = (
MI.getOpcode() == PPC::ANDIo_1_EQ_BIT8 ||
11266 MI.getOpcode() == PPC::ANDIo_1_GT_BIT8)
11269 bool isEQ = (
MI.getOpcode() == PPC::ANDIo_1_EQ_BIT ||
11270 MI.getOpcode() == PPC::ANDIo_1_EQ_BIT8);
11274 Opcode == PPC::ANDIo ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
11278 .
addReg(
MI.getOperand(1).getReg())
11281 MI.getOperand(0).getReg())
11282 .
addReg(isEQ ? PPC::CR0EQ : PPC::CR0GT);
11283 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
11289 MI.getOperand(0).getReg())
11291 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
11293 unsigned Imm =
MI.getOperand(1).getImm();
11296 MI.getOperand(0).getReg())
11298 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
11300 unsigned OldFPSCRReg =
MI.getOperand(0).getReg();
11303 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
11314 unsigned Mode =
MI.getOperand(1).getImm();
11320 }
else if (
MI.getOpcode() == PPC::SETRND) {
11328 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
11330 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
11334 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
11337 if (RC == &PPC::F8RCRegClass) {
11340 "Unsupported RegClass.");
11342 StoreOp = PPC::STFD;
11347 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
11348 "Unsupported RegClass.");
11381 unsigned OldFPSCRReg =
MI.getOperand(0).getReg();
11384 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
11398 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
11406 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
11407 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
11413 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
11420 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
11433 MI.eraseFromParent();
11446 int RefinementSteps = Subtarget.
hasRecipPrec() ? 1 : 3;
11449 return RefinementSteps;
11453 int Enabled,
int &RefinementSteps,
11454 bool &UseOneConstNR,
11455 bool Reciprocal)
const {
11476 int &RefinementSteps)
const {
11491unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
11520 Offset += cast<ConstantSDNode>(Loc.
getOperand(1))->getSExtValue();
11529 unsigned Bytes,
int Dist,
11539 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
11540 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
11543 if (FS != BFS || FS != (
int)Bytes)
return false;
11547 SDValue Base1 = Loc, Base2 = BaseLoc;
11548 int64_t Offset1 = 0, Offset2 = 0;
11551 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
11561 if (isGA1 && isGA2 && GV1 == GV2)
11562 return Offset1 == (Offset2 + Dist*Bytes);
11569 unsigned Bytes,
int Dist,
11572 EVT VT = LS->getMemoryVT();
11573 SDValue Loc = LS->getBasePtr();
11579 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
11580 default:
return false;
11581 case Intrinsic::ppc_qpx_qvlfd:
11582 case Intrinsic::ppc_qpx_qvlfda:
11585 case Intrinsic::ppc_qpx_qvlfs:
11586 case Intrinsic::ppc_qpx_qvlfsa:
11589 case Intrinsic::ppc_qpx_qvlfcd:
11590 case Intrinsic::ppc_qpx_qvlfcda:
11593 case Intrinsic::ppc_qpx_qvlfcs:
11594 case Intrinsic::ppc_qpx_qvlfcsa:
11597 case Intrinsic::ppc_qpx_qvlfiwa:
11598 case Intrinsic::ppc_qpx_qvlfiwz:
11599 case Intrinsic::ppc_altivec_lvx:
11600 case Intrinsic::ppc_altivec_lvxl:
11601 case Intrinsic::ppc_vsx_lxvw4x:
11602 case Intrinsic::ppc_vsx_lxvw4x_be:
11605 case Intrinsic::ppc_vsx_lxvd2x:
11606 case Intrinsic::ppc_vsx_lxvd2x_be:
11609 case Intrinsic::ppc_altivec_lvebx:
11612 case Intrinsic::ppc_altivec_lvehx:
11615 case Intrinsic::ppc_altivec_lvewx:
11625 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
11626 default:
return false;
11627 case Intrinsic::ppc_qpx_qvstfd:
11628 case Intrinsic::ppc_qpx_qvstfda:
11631 case Intrinsic::ppc_qpx_qvstfs:
11632 case Intrinsic::ppc_qpx_qvstfsa:
11635 case Intrinsic::ppc_qpx_qvstfcd:
11636 case Intrinsic::ppc_qpx_qvstfcda:
11639 case Intrinsic::ppc_qpx_qvstfcs:
11640 case Intrinsic::ppc_qpx_qvstfcsa:
11643 case Intrinsic::ppc_qpx_qvstfiw:
11644 case Intrinsic::ppc_qpx_qvstfiwa:
11645 case Intrinsic::ppc_altivec_stvx:
11646 case Intrinsic::ppc_altivec_stvxl:
11647 case Intrinsic::ppc_vsx_stxvw4x:
11650 case Intrinsic::ppc_vsx_stxvd2x:
11653 case Intrinsic::ppc_vsx_stxvw4x_be:
11656 case Intrinsic::ppc_vsx_stxvd2x_be:
11659 case Intrinsic::ppc_altivec_stvebx:
11662 case Intrinsic::ppc_altivec_stvehx:
11665 case Intrinsic::ppc_altivec_stvewx:
11682 SDValue Chain = LD->getChain();
11683 EVT VT = LD->getMemoryVT();
11692 while (!Queue.empty()) {
11693 SDNode *ChainNext = Queue.pop_back_val();
11694 if (!Visited.
insert(ChainNext).second)
11697 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
11701 if (!Visited.
count(ChainLD->getChain().getNode()))
11702 Queue.push_back(ChainLD->getChain().getNode());
11704 for (
const SDUse &O : ChainNext->
ops())
11705 if (!Visited.
count(O.getNode()))
11706 Queue.push_back(O.getNode());
11708 LoadRoots.
insert(ChainNext);
11720 IE = LoadRoots.
end();
I != IE; ++
I) {
11721 Queue.push_back(*
I);
11723 while (!Queue.empty()) {
11724 SDNode *LoadRoot = Queue.pop_back_val();
11725 if (!Visited.
insert(LoadRoot).second)
11728 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
11733 UE = LoadRoot->
use_end(); UI != UE; ++UI)
11734 if (((isa<MemSDNode>(*UI) &&
11735 cast<MemSDNode>(*UI)->getChain().getNode() == LoadRoot) ||
11737 Queue.push_back(*UI);
11770 auto Final = Shifted;
11781 DAGCombinerInfo &DCI)
const {
11789 if (!DCI.isAfterLegalizeDAG())
11795 UE =
N->use_end(); UI != UE; ++UI) {
11800 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
11801 auto OpSize =
N->getOperand(0).getValueSizeInBits();
11805 if (OpSize <
Size) {
11823 DAGCombinerInfo &DCI)
const {
11841 if (
N->getOperand(0).getValueType() !=
MVT::i32 &&
11842 N->getOperand(0).getValueType() !=
MVT::i64)
11850 cast<CondCodeSDNode>(
N->getOperand(
11852 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
11863 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
11876 if (Op1Known.
Zero != Op2Known.
Zero || Op1Known.
One != Op2Known.
One)
11884 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
11885 N->getOperand(0).getOpcode() !=
ISD::OR &&
11886 N->getOperand(0).getOpcode() !=
ISD::XOR &&
11896 N->getOperand(1).getOpcode() !=
ISD::AND &&
11897 N->getOperand(1).getOpcode() !=
ISD::OR &&
11898 N->getOperand(1).getOpcode() !=
ISD::XOR &&
11911 for (
unsigned i = 0; i < 2; ++i) {
11915 N->getOperand(i).getOperand(0).getValueType() ==
MVT::i1) ||
11916 isa<ConstantSDNode>(
N->getOperand(i)))
11927 while (!BinOps.
empty()) {
11936 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
11970 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
11971 if (isa<ConstantSDNode>(Inputs[i]))
11975 UE = Inputs[i].getNode()->use_end();
11997 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
11999 UE = PromOps[i].getNode()->use_end();
12022 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
12025 if (isa<ConstantSDNode>(Inputs[i]))
12031 std::list<HandleSDNode> PromOpHandles;
12032 for (
auto &PromOp : PromOps)
12033 PromOpHandles.emplace_back(PromOp);
12040 while (!PromOpHandles.empty()) {
12042 PromOpHandles.pop_back();
12048 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
12051 PromOpHandles.emplace_front(PromOp);
12056 if (isa<ConstantSDNode>(RepValue))
12065 default:
C = 0;
break;
12070 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
12078 PromOpHandles.emplace_front(PromOp);
12086 for (
unsigned i = 0; i < 2; ++i)
12087 if (isa<ConstantSDNode>(Ops[
C+i]))
12096 return N->getOperand(0);
12104 DAGCombinerInfo &DCI)
const {
12130 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
12131 N->getOperand(0).getOpcode() !=
ISD::OR &&
12132 N->getOperand(0).getOpcode() !=
ISD::XOR &&
12143 while (!BinOps.
empty()) {
12152 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
12183 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
12184 if (isa<ConstantSDNode>(Inputs[i]))
12188 UE = Inputs[i].getNode()->use_end();
12198 SelectTruncOp[0].
insert(std::make_pair(
User,
12202 SelectTruncOp[0].
insert(std::make_pair(
User,
12205 SelectTruncOp[1].
insert(std::make_pair(
User,
12211 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
12213 UE = PromOps[i].getNode()->use_end();
12223 SelectTruncOp[0].
insert(std::make_pair(
User,
12227 SelectTruncOp[0].
insert(std::make_pair(
User,
12230 SelectTruncOp[1].
insert(std::make_pair(
User,
12236 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
12237 bool ReallyNeedsExt =
false;
12241 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
12242 if (isa<ConstantSDNode>(Inputs[i]))
12246 Inputs[i].getOperand(0).getValueSizeInBits();
12247 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
12252 OpBits-PromBits))) ||
12255 (OpBits-(PromBits-1)))) {
12256 ReallyNeedsExt =
true;
12264 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
12268 if (isa<ConstantSDNode>(Inputs[i]))
12271 SDValue InSrc = Inputs[i].getOperand(0);
12285 std::list<HandleSDNode> PromOpHandles;
12286 for (
auto &PromOp : PromOps)
12287 PromOpHandles.emplace_back(PromOp);
12293 while (!PromOpHandles.empty()) {
12295 PromOpHandles.pop_back();
12299 default:
C = 0;
break;
12304 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
12312 PromOpHandles.emplace_front(PromOp);
12322 (SelectTruncOp[1].count(PromOp.
getNode()) &&
12324 PromOpHandles.emplace_front(PromOp);
12333 for (
unsigned i = 0; i < 2; ++i) {
12334 if (!isa<ConstantSDNode>(Ops[
C+i]))
12351 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
12352 if (SI0 != SelectTruncOp[0].
end())
12354 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
12355 if (SI1 != SelectTruncOp[1].
end())
12364 if (!ReallyNeedsExt)
12365 return N->getOperand(0);
12372 N->getValueSizeInBits(0), PromBits),
12373 dl,
N->getValueType(0)));
12376 "Invalid extension type");
12379 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
12387 DAGCombinerInfo &DCI)
const {
12389 "Should be called with a SETCC node");
12391 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
12407 EVT VT =
N->getValueType(0);
12414 return DAGCombineTruncBoolExt(
N, DCI);
12419 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Op.getNode()))
12433combineElementTruncationToVectorTruncation(
SDNode *
N,
12434 DAGCombinerInfo &DCI)
const {
12436 "Should be called with a BUILD_VECTOR node");
12441 SDValue FirstInput =
N->getOperand(0);
12443 "The input operand must be an fp-to-int conversion.");
12452 bool IsSplat =
true;
12457 EVT TargetVT =
N->getValueType(0);
12458 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
12459 SDValue NextOp =
N->getOperand(i);
12463 if (NextConversion != FirstConversion)
12471 if (
N->getOperand(i) != FirstInput)
12482 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
12483 SDValue In =
N->getOperand(i).getOperand(0);
12508 return DAG.
getNode(Opcode, dl, TargetVT, BV);
12521 "Should be called with a BUILD_VECTOR node");
12526 if (!
N->getValueType(0).getVectorElementType().isByteSized())
12529 bool InputsAreConsecutiveLoads =
true;
12530 bool InputsAreReverseConsecutive =
true;
12531 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
12532 SDValue FirstInput =
N->getOperand(0);
12533 bool IsRoundOfExtLoad =
false;
12538 IsRoundOfExtLoad = LD->getExtensionType() ==
ISD::EXTLOAD;
12542 N->getNumOperands() == 1)
12545 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
12547 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
12550 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
12556 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
12557 LoadSDNode *LD1 = dyn_cast<LoadSDNode>(PreviousInput);
12558 LoadSDNode *LD2 = dyn_cast<LoadSDNode>(NextInput);
12565 InputsAreConsecutiveLoads =
false;
12567 InputsAreReverseConsecutive =
false;
12570 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
12574 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
12575 "The loads cannot be both consecutive and reverse consecutive.");
12578 IsRoundOfExtLoad ? FirstInput.
getOperand(0) : FirstInput;
12580 IsRoundOfExtLoad ?
N->getOperand(
N->getNumOperands()-1).getOperand(0) :
12581 N->getOperand(
N->getNumOperands()-1);
12583 LoadSDNode *LD1 = dyn_cast<LoadSDNode>(FirstLoadOp);
12584 LoadSDNode *LDL = dyn_cast<LoadSDNode>(LastLoadOp);
12585 if (InputsAreConsecutiveLoads) {
12586 assert(LD1 &&
"Input needs to be a LoadSDNode.");
12591 if (InputsAreReverseConsecutive) {
12592 assert(LDL &&
"Input needs to be a LoadSDNode.");
12594 LDL->getBasePtr(), LDL->getPointerInfo(),
12595 LDL->getAlignment());
12597 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
12601 DAG.
getUNDEF(
N->getValueType(0)), Ops);
12610 SDValue Input, uint64_t Elems,
12611 uint64_t CorrectElems) {
12620 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
12622 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
12624 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
12625 CorrectElems = CorrectElems >> 8;
12626 Elems = Elems >> 8;
12633 EVT Ty =
N->getValueType(0);
12654 uint64_t TargetElems[] = {
12662 uint64_t Elems = 0;
12666 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
12675 SDValue Extract = Op.getOperand(0);
12686 if (Input && Input != Extract.
getOperand(0))
12692 Elems = Elems << 8;
12701 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
12702 if (!isSExtOfVecExtract(
N->getOperand(i))) {
12709 int TgtElemArrayIdx;
12711 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
12712 if (InputSize + OutputSize == 40)
12713 TgtElemArrayIdx = 0;
12714 else if (InputSize + OutputSize == 72)
12715 TgtElemArrayIdx = 1;
12716 else if (InputSize + OutputSize == 48)
12717 TgtElemArrayIdx = 2;
12718 else if (InputSize + OutputSize == 80)
12719 TgtElemArrayIdx = 3;
12720 else if (InputSize + OutputSize == 96)
12721 TgtElemArrayIdx = 4;
12725 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
12727 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
12728 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
12729 if (Elems != CorrectElems) {
12738 DAGCombinerInfo &DCI)
const {
12740 "Should be called with a BUILD_VECTOR node");
12745 if (!Subtarget.
hasVSX())
12751 SDValue FirstInput =
N->getOperand(0);
12753 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
12768 if (Subtarget.
hasP9Altivec() && !DCI.isBeforeLegalize()) {
12786 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
12790 SDValue Ext2 =
N->getOperand(1).getOperand(0);
12797 if (!Ext1Op || !Ext2Op)
12806 if (FirstElem == 0 && SecondElem == 1)
12808 else if (FirstElem == 2 && SecondElem == 3)
12821 DAGCombinerInfo &DCI)
const {
12824 "Need an int -> FP conversion node here");
12837 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(
MVT::i1) ||
12838 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(
MVT::i64))
12841 SDValue FirstOperand(
Op.getOperand(0));
12842 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
12843 (FirstOperand.getValueType() ==
MVT::i8 ||
12844 FirstOperand.getValueType() ==
MVT::i16);
12847 bool DstDouble =
Op.getValueType() ==
MVT::f64;
12848 unsigned ConvOp =
Signed ?
12854 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
12862 SDValue ExtOps[] = { Ld, WidthConst };
12874 if (
Op.getOperand(0).getValueType() ==
MVT::i32)
12878 "UINT_TO_FP is supported only with FPCVT");
12896 SDValue Src =
Op.getOperand(0).getOperand(0);
12899 DCI.AddToWorklist(Src.
getNode());
12915 DCI.AddToWorklist(
FP.getNode());
12934 switch (
N->getOpcode()) {
12939 Chain = LD->getChain();
12940 Base = LD->getBasePtr();
12941 MMO = LD->getMemOperand();
12960 MVT VecTy =
N->getValueType(0).getSimpleVT();
12969 SDValue LoadOps[] = { Chain, Base };
12975 Chain = Load.getValue(1);
13003 switch (
N->getOpcode()) {
13008 Chain = ST->getChain();
13009 Base = ST->getBasePtr();
13010 MMO = ST->getMemOperand();
13030 SDValue Src =
N->getOperand(SrcOpnd);
13050 SDValue StoreOps[] = { Chain, Swap, Base };
13053 StoreOps, VecTy, MMO);
13060 DAGCombinerInfo &DCI)
const {
13064 unsigned Opcode =
N->getOperand(1).getOpcode();
13067 &&
"Not a FP_TO_INT Instruction!");
13069 SDValue Val =
N->getOperand(1).getOperand(0);
13070 EVT Op1VT =
N->getOperand(1).getValueType();
13078 bool ValidTypeForStoreFltAsInt =
13083 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
13089 DCI.AddToWorklist(Val.
getNode());
13097 Val = DAG.
getNode(ConvOpcode,
13099 DCI.AddToWorklist(Val.
getNode());
13103 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
13109 cast<StoreSDNode>(
N)->getMemoryVT(),
13110 cast<StoreSDNode>(
N)->getMemOperand());
13112 DCI.AddToWorklist(Val.
getNode());
13120 switch (
N->getOpcode()) {
13123 return combineADD(
N, DCI);
13125 return combineSHL(
N, DCI);
13127 return combineSRA(
N, DCI);
13129 return combineSRL(
N, DCI);
13131 return combineMUL(
N, DCI);
13134 return N->getOperand(0);
13138 return N->getOperand(0);
13142 if (
C->isNullValue() ||
13143 C->isAllOnesValue())
13144 return N->getOperand(0);
13150 return DAGCombineExtBoolTrunc(
N, DCI);
13152 return combineTRUNCATE(
N, DCI);
13154 if (
SDValue CSCC = combineSetCC(
N, DCI))
13158 return DAGCombineTruncBoolExt(
N, DCI);
13161 return combineFPToIntToFP(
N, DCI);
13164 EVT Op1VT =
N->getOperand(1).getValueType();
13165 unsigned Opcode =
N->getOperand(1).getOpcode();
13168 SDValue Val= combineStoreFPToInt(
N, DCI);
13174 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
13175 N->getOperand(1).getNode()->hasOneUse() &&
13181 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
13185 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
13192 if (Op1VT.
bitsGT(mVT)) {
13202 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
13206 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
13207 cast<StoreSDNode>(
N)->getMemOperand());
13213 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT ==
MVT::i32) {
13215 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
13225 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
13242 EVT VT = LD->getValueType(0);
13261 auto ReplaceTwoFloatLoad = [&]() {
13277 if (!LD->hasNUsesOfValue(2, 0))
13280 auto UI = LD->use_begin();
13281 while (UI.getUse().getResNo() != 0) ++UI;
13283 while (UI.getUse().getResNo() != 0) ++UI;
13284 SDNode *RightShift = *UI;
13292 if (RightShift->getOpcode() !=
ISD::SRL ||
13293 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
13294 RightShift->getConstantOperandVal(1) != 32 ||
13295 !RightShift->hasOneUse())
13298 SDNode *Trunc2 = *RightShift->use_begin();
13308 Bitcast->getValueType(0) !=
MVT::f32)
13320 SDValue BasePtr = LD->getBasePtr();
13321 if (LD->isIndexed()) {
13323 "Non-pre-inc AM on PPC?");
13332 LD->getPointerInfo(), LD->getAlignment(),
13333 MMOFlags, LD->getAAInfo());
13339 LD->getPointerInfo().getWithOffset(4),
13340 MinAlign(LD->getAlignment(), 4), MMOFlags, LD->getAAInfo());
13342 if (LD->isIndexed()) {
13356 if (ReplaceTwoFloatLoad())
13359 EVT MemVT = LD->getMemoryVT();
13364 if (LD->isUnindexed() && VT.
isVector() &&
13370 LD->getAlignment() >= ScalarABIAlignment)) &&
13371 LD->getAlignment() < ABIAlignment) {
13373 SDValue Chain = LD->getChain();
13374 SDValue Ptr = LD->getBasePtr();
13402 MVT PermCntlTy, PermTy, LDTy;
13404 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr :
13405 Intrinsic::ppc_altivec_lvsl;
13406 IntrLD = Intrinsic::ppc_altivec_lvx;
13407 IntrPerm = Intrinsic::ppc_altivec_vperm;
13413 Intrinsic::ppc_qpx_qvlpcls;
13414 IntrLD = MemVT ==
MVT::v4f64 ? Intrinsic::ppc_qpx_qvlfd :
13415 Intrinsic::ppc_qpx_qvlfs;
13416 IntrPerm = Intrinsic::ppc_qpx_qvfperm;
13438 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
13442 BaseLoadOps, LDTy, BaseMMO);
13451 int IncValue = IncOffset;
13468 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
13472 ExtraLoadOps, LDTy, ExtraMMO);
13483 if (isLittleEndian)
13485 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
13488 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
13507 unsigned IID = cast<ConstantSDNode>(
N->getOperand(0))->getZExtValue();
13509 : Intrinsic::ppc_altivec_lvsl);
13510 if ((IID ==
Intr ||
13511 IID == Intrinsic::ppc_qpx_qvlpcld ||
13512 IID == Intrinsic::ppc_qpx_qvlpcls) &&
13513 N->getOperand(1)->getOpcode() ==
ISD::ADD) {
13516 int Bits = IID == Intrinsic::ppc_qpx_qvlpcld ?
13521 .
zext(Add.getScalarValueSizeInBits()))) {
13522 SDNode *BasePtr = Add->getOperand(0).getNode();
13524 UE = BasePtr->use_end();
13527 cast<ConstantSDNode>(UI->getOperand(0))->getZExtValue() == IID) {
13537 if (isa<ConstantSDNode>(Add->getOperand(1))) {
13538 SDNode *BasePtr = Add->getOperand(0).getNode();
13540 UE = BasePtr->use_end(); UI != UE; ++UI) {
13541 if (UI->getOpcode() ==
ISD::ADD &&
13542 isa<ConstantSDNode>(UI->getOperand(1)) &&
13543 (cast<ConstantSDNode>(Add->getOperand(1))->getZExtValue() -
13544 cast<ConstantSDNode>(UI->getOperand(1))->getZExtValue()) %
13545 (1ULL << Bits) == 0) {
13550 cast<ConstantSDNode>(
VI->getOperand(0))->getZExtValue() == IID) {
13562 (IID == Intrinsic::ppc_altivec_vmaxsw ||
13563 IID == Intrinsic::ppc_altivec_vmaxsh ||
13564 IID == Intrinsic::ppc_altivec_vmaxsb)) {
13580 V2.getOperand(1) == V1) {
13598 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
13601 case Intrinsic::ppc_vsx_lxvw4x:
13602 case Intrinsic::ppc_vsx_lxvd2x:
13611 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
13614 case Intrinsic::ppc_vsx_stxvw4x:
13615 case Intrinsic::ppc_vsx_stxvd2x:
13623 N->getOperand(0).hasOneUse() &&
13639 Ops, LD->getMemoryVT(), LD->getMemOperand());
13663 if (!
N->getOperand(0).hasOneUse() &&
13664 !
N->getOperand(1).hasOneUse() &&
13665 !
N->getOperand(2).hasOneUse()) {
13668 SDNode *VCMPoNode =
nullptr;
13670 SDNode *LHSN =
N->getOperand(0).getNode();
13674 UI->getOperand(1) ==
N->getOperand(1) &&
13675 UI->getOperand(2) ==
N->getOperand(2) &&
13676 UI->getOperand(0) ==
N->getOperand(0)) {
13689 SDNode *FlagUser =
nullptr;
13691 FlagUser ==
nullptr; ++UI) {
13705 return SDValue(VCMPoNode, 0);
13713 cast<ConstantSDNode>(Cond.getOperand(1))->getZExtValue() ==
13714 Intrinsic::loop_decrement) {
13719 assert(Cond.getNode()->hasOneUse() &&
13720 "Counter decrement has more than one use");
13732 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(1))->get();
13733 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
13740 Intrinsic::loop_decrement &&
13746 cast<ConstantSDNode>(LHS.
getOperand(1))->getZExtValue() ==
13747 Intrinsic::loop_decrement &&
13748 isa<ConstantSDNode>(RHS)) {
13750 "Counter decrement comparison is not EQ or NE");
13752 unsigned Val = cast<ConstantSDNode>(RHS)->getZExtValue();
13760 "Counter decrement has more than one use");
13763 N->getOperand(0),
N->getOperand(4));
13772 assert(isDot &&
"Can't compare against a vector result!");
13776 unsigned Val = cast<ConstantSDNode>(RHS)->getZExtValue();
13777 if (Val != 0 && Val != 1) {
13779 return N->getOperand(0);
13782 N->getOperand(0),
N->getOperand(4));
13785 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
13798 switch (cast<ConstantSDNode>(LHS.
getOperand(1))->getZExtValue()) {
13817 N->getOperand(4), CompNode.
getValue(1));
13822 return DAGCombineBuildVector(
N, DCI);
13824 return combineABS(
N, DCI);
13826 return combineVSelect(
N, DCI);
13837 EVT VT =
N->getValueType(0);
13841 !(Divisor.
isPowerOf2() || (-Divisor).isPowerOf2()))
13847 bool IsNegPow2 = (-Divisor).isPowerOf2();
13868 const APInt &DemandedElts,
13870 unsigned Depth)
const {
13872 switch (Op.getOpcode()) {
13876 if (cast<VTSDNode>(Op.getOperand(2))->getVT() ==
MVT::i16)
13877 Known.
Zero = 0xFFFF0000;
13881 switch (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue()) {
13883 case Intrinsic::ppc_altivec_vcmpbfp_p:
13884 case Intrinsic::ppc_altivec_vcmpeqfp_p:
13885 case Intrinsic::ppc_altivec_vcmpequb_p:
13886 case Intrinsic::ppc_altivec_vcmpequh_p:
13887 case Intrinsic::ppc_altivec_vcmpequw_p:
13888 case Intrinsic::ppc_altivec_vcmpequd_p:
13889 case Intrinsic::ppc_altivec_vcmpgefp_p:
13890 case Intrinsic::ppc_altivec_vcmpgtfp_p:
13891 case Intrinsic::ppc_altivec_vcmpgtsb_p:
13892 case Intrinsic::ppc_altivec_vcmpgtsh_p:
13893 case Intrinsic::ppc_altivec_vcmpgtsw_p:
13894 case Intrinsic::ppc_altivec_vcmpgtsd_p:
13895 case Intrinsic::ppc_altivec_vcmpgtub_p:
13896 case Intrinsic::ppc_altivec_vcmpgtuh_p:
13897 case Intrinsic::ppc_altivec_vcmpgtuw_p:
13898 case Intrinsic::ppc_altivec_vcmpgtud_p:
13934 uint64_t LoopSize = 0;
13936 for (
auto J = (*I)->begin(), JE = (*I)->end(); J != JE; ++J) {
13937 LoopSize +=
TII->getInstSizeInBytes(*J);
13942 if (LoopSize > 16 && LoopSize <= 32)
13956 if (Constraint.
size() == 1) {
13957 switch (Constraint[0]) {
13975 }
else if (Constraint ==
"wc") {
13977 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
13978 Constraint ==
"wf" || Constraint ==
"ws" ||
13979 Constraint ==
"wi" || Constraint ==
"ww") {
13992 Value *CallOperandVal =
info.CallOperandVal;
13995 if (!CallOperandVal)
14002 else if ((
StringRef(constraint) ==
"wa" ||
14014 switch (*constraint) {
14044std::pair<unsigned, const TargetRegisterClass *>
14048 if (Constraint.
size() == 1) {
14050 switch (Constraint[0]) {
14053 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
14054 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
14057 return std::make_pair(0U, &PPC::G8RCRegClass);
14058 return std::make_pair(0U, &PPC::GPRCRegClass);
14064 if (Subtarget.
hasSPE()) {
14066 return std::make_pair(0U, &PPC::SPE4RCRegClass);
14068 return std::make_pair(0U, &PPC::SPERCRegClass);
14071 return std::make_pair(0U, &PPC::F4RCRegClass);
14073 return std::make_pair(0U, &PPC::F8RCRegClass);
14075 return std::make_pair(0U, &PPC::QFRCRegClass);
14077 return std::make_pair(0U, &PPC::QSRCRegClass);
14082 return std::make_pair(0U, &PPC::QFRCRegClass);
14084 return std::make_pair(0U, &PPC::QSRCRegClass);
14086 return std::make_pair(0U, &PPC::VRRCRegClass);
14089 return std::make_pair(0U, &PPC::CRRCRegClass);
14091 }
else if (Constraint ==
"wc" && Subtarget.
useCRBits()) {
14093 return std::make_pair(0U, &PPC::CRBITRCRegClass);
14094 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
14095 Constraint ==
"wf" || Constraint ==
"wi") &&
14097 return std::make_pair(0U, &PPC::VSRCRegClass);
14098 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.
hasVSX()) {
14100 return std::make_pair(0U, &PPC::VSSRCRegClass);
14102 return std::make_pair(0U, &PPC::VSFRCRegClass);
14105 std::pair<unsigned, const TargetRegisterClass *> R =
14115 PPC::GPRCRegClass.contains(R.first))
14116 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
14117 PPC::sub_32, &PPC::G8RCRegClass),
14118 &PPC::G8RCRegClass);
14121 if (!R.second &&
StringRef(
"{cc}").equals_lower(Constraint)) {
14122 R.first = PPC::CR0;
14123 R.second = &PPC::CRRCRegClass;
14132 std::string &Constraint,
14133 std::vector<SDValue>&Ops,
14138 if (Constraint.length() > 1)
return;
14140 char Letter = Constraint[0];
14164 if (isShiftedUInt<16, 16>(
Value))
14168 if (isShiftedInt<16, 16>(
Value))
14196 if (Result.getNode()) {
14197 Ops.push_back(Result);
14223 switch (AM.
Scale) {
14254 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
14260 bool isPPC64 = Subtarget.
isPPC64();
14264 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
14274 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
14282 unsigned Depth = cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
14295 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
14297 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
14311 bool isPPC64 = Subtarget.
isPPC64();
14321 .
Case(
"r2", (isDarwinABI || isPPC64) ? 0 : PPC::R2)
14322 .
Case(
"r13", (!isPPC64 && isDarwinABI) ? 0 :
14323 (
is64Bit ? PPC::X13 : PPC::R13))
14345 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
14369 unsigned Intrinsic)
const {
14370 switch (Intrinsic) {
14371 case Intrinsic::ppc_qpx_qvlfd:
14372 case Intrinsic::ppc_qpx_qvlfs:
14373 case Intrinsic::ppc_qpx_qvlfcd:
14374 case Intrinsic::ppc_qpx_qvlfcs:
14375 case Intrinsic::ppc_qpx_qvlfiwa:
14376 case Intrinsic::ppc_qpx_qvlfiwz:
14377 case Intrinsic::ppc_altivec_lvx:
14378 case Intrinsic::ppc_altivec_lvxl:
14379 case Intrinsic::ppc_altivec_lvebx:
14380 case Intrinsic::ppc_altivec_lvehx:
14381 case Intrinsic::ppc_altivec_lvewx:
14382 case Intrinsic::ppc_vsx_lxvd2x:
14383 case Intrinsic::ppc_vsx_lxvw4x: {
14385 switch (Intrinsic) {
14386 case Intrinsic::ppc_altivec_lvebx:
14389 case Intrinsic::ppc_altivec_lvehx:
14392 case Intrinsic::ppc_altivec_lvewx:
14395 case Intrinsic::ppc_vsx_lxvd2x:
14398 case Intrinsic::ppc_qpx_qvlfd:
14401 case Intrinsic::ppc_qpx_qvlfs:
14404 case Intrinsic::ppc_qpx_qvlfcd:
14407 case Intrinsic::ppc_qpx_qvlfcs:
14417 Info.ptrVal =
I.getArgOperand(0);
14424 case Intrinsic::ppc_qpx_qvlfda:
14425 case Intrinsic::ppc_qpx_qvlfsa:
14426 case Intrinsic::ppc_qpx_qvlfcda:
14427 case Intrinsic::ppc_qpx_qvlfcsa:
14428 case Intrinsic::ppc_qpx_qvlfiwaa:
14429 case Intrinsic::ppc_qpx_qvlfiwza: {
14431 switch (Intrinsic) {
14432 case Intrinsic::ppc_qpx_qvlfda:
14435 case Intrinsic::ppc_qpx_qvlfsa:
14438 case Intrinsic::ppc_qpx_qvlfcda:
14441 case Intrinsic::ppc_qpx_qvlfcsa:
14451 Info.ptrVal =
I.getArgOperand(0);
14458 case Intrinsic::ppc_qpx_qvstfd:
14459 case Intrinsic::ppc_qpx_qvstfs:
14460 case Intrinsic::ppc_qpx_qvstfcd:
14461 case Intrinsic::ppc_qpx_qvstfcs:
14462 case Intrinsic::ppc_qpx_qvstfiw:
14463 case Intrinsic::ppc_altivec_stvx:
14464 case Intrinsic::ppc_altivec_stvxl:
14465 case Intrinsic::ppc_altivec_stvebx:
14466 case Intrinsic::ppc_altivec_stvehx:
14467 case Intrinsic::ppc_altivec_stvewx:
14468 case Intrinsic::ppc_vsx_stxvd2x:
14469 case Intrinsic::ppc_vsx_stxvw4x: {
14471 switch (Intrinsic) {
14472 case Intrinsic::ppc_altivec_stvebx:
14475 case Intrinsic::ppc_altivec_stvehx:
14478 case Intrinsic::ppc_altivec_stvewx:
14481 case Intrinsic::ppc_vsx_stxvd2x:
14484 case Intrinsic::ppc_qpx_qvstfd:
14487 case Intrinsic::ppc_qpx_qvstfs:
14490 case Intrinsic::ppc_qpx_qvstfcd:
14493 case Intrinsic::ppc_qpx_qvstfcs:
14503 Info.ptrVal =
I.getArgOperand(1);
14510 case Intrinsic::ppc_qpx_qvstfda:
14511 case Intrinsic::ppc_qpx_qvstfsa:
14512 case Intrinsic::ppc_qpx_qvstfcda:
14513 case Intrinsic::ppc_qpx_qvstfcsa:
14514 case Intrinsic::ppc_qpx_qvstfiwa: {
14516 switch (Intrinsic) {
14517 case Intrinsic::ppc_qpx_qvstfda:
14520 case Intrinsic::ppc_qpx_qvstfsa:
14523 case Intrinsic::ppc_qpx_qvstfcda:
14526 case Intrinsic::ppc_qpx_qvstfcsa:
14536 Info.ptrVal =
I.getArgOperand(1);
14562 uint64_t
Size,
unsigned DstAlign,
unsigned SrcAlign,
bool IsMemset,
14563 bool ZeroMemset,
bool MemcpyStrSrc,
14568 if (Subtarget.
hasQPX() &&
Size >= 32 && (!IsMemset ||
Size >= 64) &&
14569 (!SrcAlign || SrcAlign >= 32) && (!DstAlign || DstAlign >= 32) &&
14577 (((!SrcAlign || SrcAlign >= 16) && (!DstAlign || DstAlign >= 16)) ||
14596 return !(BitSize == 0 || BitSize > 64);
14604 return NumBits1 == 64 && NumBits2 == 32;
14612 return NumBits1 == 64 && NumBits2 == 32;
14618 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
14619 EVT MemVT = LD->getMemoryVT();
14637 "invalid fpext types");
14656 bool *Fast)
const {
14670 if (Subtarget.
hasVSX()) {
14713 static const MCPhysReg ScratchRegs[] = {
14714 PPC::X12, PPC::LR8, PPC::CTR8, 0
14717 return ScratchRegs;
14721 const Constant *PersonalityFn)
const {
14722 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
14726 const Constant *PersonalityFn)
const {
14727 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
14732 EVT VT ,
unsigned DefinedValues)
const {
14758 if (!Subtarget.
isPPC64())
return;
14779 RC = &PPC::G8RCRegClass;
14780 else if (PPC::F8RCRegClass.
contains(*
I))
14781 RC = &PPC::F8RCRegClass;
14782 else if (PPC::CRRCRegClass.
contains(*
I))
14783 RC = &PPC::CRRCRegClass;
14784 else if (PPC::VRRCRegClass.
contains(*
I))
14785 RC = &PPC::VRRCRegClass;
14789 unsigned NewVR =
MRI->createVirtualRegister(RC);
14795 assert(
Entry->getParent()->getFunction().hasFnAttribute(
14796 Attribute::NoUnwind) &&
14797 "Function should be nounwind in insertCopiesSplitCSR!");
14803 for (
auto *Exit : Exits)
14805 TII->get(TargetOpcode::COPY), *
I)
14824 bool ForCodeSize)
const {
14848 unsigned Opcode =
N->getOpcode();
14849 unsigned TargetOpcode;
14868 if (Mask->getZExtValue() == OpSizeInBits - 1)
14874SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
14883 CN1 ==
nullptr ||
N->getValueType(0) !=
MVT::i64)
14904SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
14911SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
14930 auto isZextOfCompareWithConstant = [](
SDValue Op) {
14935 SDValue Cmp = Op.getOperand(0);
14936 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
14937 Cmp.getOperand(0).getValueType() !=
MVT::i64)
14940 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
14941 int64_t NegConstant = 0 -
Constant->getSExtValue();
14950 bool LHSHasPattern = isZextOfCompareWithConstant(LHS);
14951 bool RHSHasPattern = isZextOfCompareWithConstant(RHS);
14954 if (LHSHasPattern && !RHSHasPattern)
14956 else if (!LHSHasPattern && !RHSHasPattern)
14963 auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1));
14966 int64_t NegConstant = 0 -
Constant->getSExtValue();
14968 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
14979 SDValue AddOrZ = NegConstant != 0 ? Add :
Z;
14994 SDValue AddOrZ = NegConstant != 0 ? Add :
Z;
15005SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
15022 DAGCombinerInfo &DCI)
const {
15026 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
15027 return CRTruncValue;
15037 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
15047 EltToExtract = EltToExtract ? 0 : 1;
15057 return DCI.DAG.getNode(
15059 DCI.DAG.getTargetConstant(EltToExtract, dl,
MVT::i32));
15064SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
15068 if (!ConstOpOrElement)
15076 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
15097 return IsAddOne && IsNeg ? VT.
isVector() :
true;
15101 EVT VT =
N->getValueType(0);
15108 if ((MulAmtAbs - 1).isPowerOf2()) {
15112 if (!IsProfitable(IsNeg,
true, VT))
15118 DAG.
getConstant((MulAmtAbs - 1).logBase2(), DL, VT));
15125 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
15129 if (!IsProfitable(IsNeg,
false, VT))
15135 DAG.
getConstant((MulAmtAbs + 1).logBase2(), DL, VT));
15147bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
15158 auto Attr =
Caller->getFnAttribute(
"disable-tail-calls");
15159 if (Attr.getValueAsString() ==
"true")
15182bool PPCTargetLowering::hasBitPreservingFPLogic(
EVT VT)
const {
15183 if (!Subtarget.
hasVSX())
15191bool PPCTargetLowering::
15192isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
15195 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
15197 if (CI->getBitWidth() > 64)
15199 int64_t ConstVal = CI->getZExtValue();
15201 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
15213SDValue PPCTargetLowering::combineABS(
SDNode *
N, DAGCombinerInfo &DCI)
const {
15216 "Only combine this when P9 altivec supported!");
15217 EVT VT =
N->getValueType(0);
15223 if (
N->getOperand(0).getOpcode() ==
ISD::SUB) {
15226 unsigned SubOpcd0 =
N->getOperand(0)->getOperand(0).getOpcode();
15227 unsigned SubOpcd1 =
N->getOperand(0)->getOperand(1).getOpcode();
15233 N->getOperand(0)->getOperand(0),
15234 N->getOperand(0)->getOperand(1),
15239 if (
N->getOperand(0).getValueType() ==
MVT::v4i32 &&
15240 N->getOperand(0).hasOneUse()) {
15242 N->getOperand(0)->getOperand(0),
15243 N->getOperand(0)->getOperand(1),
15257 DAGCombinerInfo &DCI)
const {
15260 "Only combine this when P9 altivec supported!");
15265 SDValue TrueOpnd =
N->getOperand(1);
15266 SDValue FalseOpnd =
N->getOperand(2);
15267 EVT VT =
N->getOperand(1).getValueType();
15281 ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
15296 SDValue CmpOpnd1 = Cond.getOperand(0);
15297 SDValue CmpOpnd2 = Cond.getOperand(1);
15307 CmpOpnd1, CmpOpnd2,
unsigned const MachineRegisterInfo * MRI
static SDValue GeneratePerfectShuffle(unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static const unsigned PerfectShuffleTable[6561+1]
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
unsigned const TargetRegisterInfo * TRI
static bool isConstantOrUndef(const SDValue Op)
Module.h This file contains the declarations for the Module class.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static const MCPhysReg QFPR[]
QFPR - The set of QPX registers that should be allocated for arguments.
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static bool callsShareTOCBase(const Function *Caller, SDValue Callee, const TargetMachine &TM)
static bool hasSameArgumentList(const Function *CallerFn, ImmutableCallSite CS)
static bool isFunctionGlobalAddress(SDValue Callee)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag, SDValue &Chain, SDValue CallSeqStart, const SDLoc &dl, int SPDiff, bool isTailCall, bool isPatchPoint, bool hasNest, SmallVectorImpl< std::pair< unsigned, SDValue > > &RegsToPass, SmallVectorImpl< SDValue > &Ops, std::vector< EVT > &NodeTys, ImmutableCallSite CS, const PPCSubtarget &Subtarget)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs, bool HasQPX)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments, on Darwin.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static void getBaseWithConstantOffset(SDValue Loc, SDValue &Base, int64_t &Offset, SelectionDAG &DAG)
static void setUsesTOCBasePtr(MachineFunction &MF)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InFlag, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static Instruction * callIntrinsic(IRBuilder<> &Builder, Intrinsic::ID Id)
static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static void getMaxByValAlign(Type *Ty, unsigned &MaxAlign, unsigned MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue getTOCEntry(SelectionDAG &DAG, const SDLoc &dl, bool Is64Bit, SDValue GA)
cl::opt< bool > ANDIGlueBug
static cl::opt< bool > EnableQuadPrecision("enable-ppc-quad-precision", cl::desc("enable quad precision float support on ppc"), cl::Hidden)
static SDValue BuildSplatI(int Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildSplatI - Build a canonical splati of Val with an element size of SplatSize.
static unsigned CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSplat(ArrayRef< Value * > VL)
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
This defines the Use class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool is64Bit(const char *name)
unsigned getPrefLoopAlignment() const
Class for arbitrary precision integers.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
APInt abs() const
Get the absolute value;.
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
bool isNegative() const
Determine sign of this APInt.
bool getBoolValue() const
Convert APInt to a boolean value.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but may be faster.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
unsigned getLocMemOffset() const
Register getLocReg() const
LocInfo getLocInfo() const
unsigned getValNo() const
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
CallingConv::ID getCallingConv() const
This class represents a function call, abstracting a target machine's calling convention.
ValTy * getCalledValue() const
Return the pointer to function that is being called.
unsigned arg_size() const
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
TargetLoweringBase::ArgListTy ArgListTy
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool CanLowerReturn
CanLowerReturn - true iff the function's return value can be lowered to registers.
int64_t getOffset() const
const GlobalValue * getGlobal() const
VisibilityTypes getVisibility() const
LinkageTypes getLinkage() const
StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
BasicBlock * GetInsertBlock() const
Type * getFloatTy()
Fetch the type representing a 32-bit floating point value.
Type * getVoidTy()
Fetch the type representing void.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Establish a view to a call site for examination.
const BasicBlock * getParent() const
bool hasAtomicLoad() const
Return true if this atomic instruction loads from memory.
NodeT & get() const
get - Dereference as a NodeT reference.
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
const std::vector< LoopT * > & getSubLoops() const
Return the loops contained entirely within this loop.
unsigned getLoopDepth() const
Return the nesting level of this loop.
block_iterator block_end() const
block_iterator block_begin() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
static MVT getFloatingPointVT(unsigned BitWidth)
bool isVector() const
Return true if this is a vector value type.
static mvt_range integer_valuetypes()
unsigned getScalarSizeInBits() const
static mvt_range vector_valuetypes()
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
unsigned getSizeInBits() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static mvt_range fp_valuetypes()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MachineModuleInfo & getMMI() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
unsigned addLiveIn(unsigned PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
uint64_t getAlignment() const
Return the minimum known alignment in bytes of the actual memory reference.
uint64_t getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
const MCContext & getContext() const
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
static MachineOperand CreateImm(int64_t Val)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
unsigned getLiveInVirtReg(unsigned PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in physical ...
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
unsigned getAlignment() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
unsigned getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
unsigned getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
unsigned getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void addLiveInAttr(unsigned VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
void setReturnAddrSaveIndex(int idx)
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
void setTailCallSPDelta(int size)
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
int getVarArgsStackOffset() const
void setIsSplitCSR(bool s)
void setFramePointerSaveIndex(int Idx)
bool useLongCalls() const
unsigned char classifyGlobalReference(const GlobalValue *GV) const
classifyGlobalReference - Classify a global variable reference for the current subtarget accourding t...
bool useSoftFloat() const
bool use64BitRegs() const
use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit registers in 32-bit mode when...
const PPCFrameLowering * getFrameLowering() const override
bool hasLazyResolverStub(const GlobalValue *GV) const
hasLazyResolverStub - Return true if accesses to the specified global have to go through a dyld lazy ...
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool needsTwoConstNR() const
unsigned getDarwinDirective() const
getDarwinDirective - Returns the -m directive specified for the cpu.
const PPCInstrInfo * getInstrInfo() const override
bool useCRBits() const
useCRBits - Return true if we should store and manipulate i1 values in the individual condition regis...
bool hasRecipPrec() const
bool hasInvariantFunctionDescriptors() const
POPCNTDKind hasPOPCNTD() const
bool hasPartwordAtomics() const
bool isLittleEndian() const
bool isTargetLinux() const
bool hasP9Altivec() const
bool isDarwin() const
isDarwin - True if this is any darwin platform.
bool has64BitSupport() const
has64BitSupport - Return true if the selected CPU supports 64-bit instructions, regardless of whether...
bool enableMachineScheduler() const override
Scheduling customization.
const PPCRegisterInfo * getRegisterInfo() const override
bool hasDirectMove() const
bool hasP8Altivec() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
unsigned getRegisterByName(const char *RegName, EVT VT, SelectionDAG &DAG) const override
Return the register ID of the name passed in.
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
void insertCopiesSplitCSR(MachineBasicBlock *Entry, const SmallVectorImpl< MachineBasicBlock * > &Exits) const override
Insert explicit copies in entry and exit blocks.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
void initializeSplitCSR(MachineBasicBlock *Entry) const override
Perform necessary initialization to handle a subset of CSRs explicitly via copies.
unsigned getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always beneficiates from combining into FMA for a given value type.
Instruction * emitLeadingFence(IRBuilder<> &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
unsigned getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
unsigned getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc, const AttributeList &FuncAttributes) const override
getOptimalMemOpType - Returns the target specific optimal type for load and store operations as a res...
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, unsigned Align=1, MachineMemOperand::Flags Flags=MachineMemOperand::MONone, bool *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, unsigned EncodingAlignment=0) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool isFMAFasterThanFMulAndFAdd(EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, unsigned EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool isJumpTableRelative() const override
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
Instruction * emitTrailingFence(IRBuilder<> &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
const PseudoSourceValue * getGOT()
Return a pseudo source value referencing the global offset table (or something the like).
const PseudoSourceValue * getStack()
Return a pseudo source value referencing the area below the stack frame of a function,...
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
const SDNodeFlags getFlags() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned char TargetFlags=0)
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue CreateStackTemporary(EVT VT, unsigned minAlign=1)
Create a stack temporary, suitable for holding the specified value type.
SDValue getTargetConstantPool(const Constant *C, EVT VT, unsigned Align=0, int Offset=0, unsigned char TargetFlags=0)
const TargetLowering & getTargetLoweringInfo() const
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags=0)
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getIndexedStore(SDValue OrigStore, const SDLoc &dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM)
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, unsigned Align=0, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, unsigned Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getConstantPool(const Constant *C, EVT VT, unsigned Align=0, int Offs=0, bool isT=false, unsigned char TargetFlags=0)
LLVMContext * getContext() const
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getIndexedLoad(SDValue OrigLoad, const SDLoc &dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
int getSplatIndex() const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const_iterator begin() const
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const_iterator end() const
LLVM_NODISCARD bool empty() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
LLVM_NODISCARD size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
LLVM_NODISCARD R Default(T Value)
StringSwitch & Case(StringLiteral S, T Value)
Class to represent struct types.
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
void setTargetDAGCombine(ISD::NodeType NT)
Targets should invoke this method for each target independent node that they want to provide a custom...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
virtual bool isJumpTableRelative() const
unsigned MaxStoresPerMemcpyOptSize
Maximum number of store operations that may be substituted for a call to memcpy, used for functions w...
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setIndexedStoreAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
bool isOperationLegalOrCustom(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
void setUseUnderscoreSetJmp(bool Val)
Indicate whether this target prefers to use _setjmp to implement llvm.setjmp or the version without _...
void setPrefLoopAlignment(unsigned Align)
Set the target's preferred loop alignment.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setUseUnderscoreLongJmp(bool Val)
Indicate whether this target prefers to use _longjmp to implement llvm.longjmp or the version without...
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setMinFunctionAlignment(unsigned Align)
Set the target's minimum function alignment (in log2(bytes))
unsigned MaxStoresPerMemsetOptSize
Maximum number of stores operations that may be substituted for the call to memset,...
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum bytes of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void setPrefFunctionAlignment(unsigned Align)
Set the target's preferred function alignment.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
unsigned MaxStoresPerMemmoveOptSize
Maximum number of store instructions that may be substituted for a call to memmove,...
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
void setStackPointerRegisterToSaveRestore(unsigned R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
unsigned MaxLoadsPerMemcmpOptSize
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
void setMinStackArgumentAlignment(unsigned Align)
Set the minimum stack alignment of an argument (in log2(bytes)).
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum bytes of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
void setIndexedLoadAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
CodeModel::Model getCodeModel() const
Returns the code model.
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
self_iterator getIterator()
arg_iterator - Iterates through arguments stored inside an ArgList.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char IsConst[]
Key for Kernel::Arg::Metadata::mIsConst.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Fast
Fast - This calling convention attempts to make calls as fast as possible (e.g.
@ C
C - The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ FLT_ROUNDS_
FLT_ROUNDS_ - Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest 2 Round to ...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ FGETSIGN
INT = FGETSIGN(FP) - Return the sign bit of the specified floating point value as an integer 0/1 valu...
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ FP_ROUND_INREG
X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and rounds it to a floating point val...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an vector value) starting with the ...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the specified, possibly variable,...
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ MO_NLP_FLAG
MO_NLP_FLAG - If this bit is set, the symbol reference is actually to the non_lazy_ptr for the global...
@ MO_NLP_HIDDEN_FLAG
MO_NLP_HIDDEN_FLAG - If this bit is set, the symbol reference is to a symbol with hidden visibility.
@ MO_PLT
On a symbol operand "FOO", this indicates that the reference is actually to "FOO@plt".
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ QBFLT
QBFLT = Access the underlying QPX floating-point boolean representation.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ QVGPCI
QVGPCI = This corresponds to the QPX qvgpci instruction.
@ VABSD
An SDNode for Power9 vector absolute value difference.
@ ANDIo_1_EQ_BIT
i1 = ANDIo_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after execu...
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ QVFPERM
QVFPERM = This corresponds to the QPX qvfperm instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ VCMPo
RESVEC, OUTFLAG = VCMPo(LHS, RHS, OPC) - Represents one of the altivec VCMP*o instructions.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ FP_TO_UINT_IN_VSR
Floating-point-to-interger conversion instructions.
@ FP_EXTEND_LH
Custom extend v4f32 to v2f64.
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS model, produces an ADD instruction that ...
@ QVLFSb
QBRC, CHAIN = QVLFSb CHAIN, Ptr The 4xf32 load used for v4i1 constants.
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ XXREVERSE
XXREVERSE - The PPC VSX reverse instruction.
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ SExtVElems
SExtVElems, takes an input vector of a smaller type and sign extends to an output vector of a larger ...
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ GlobalBaseReg
GlobalBaseReg - On Darwin, this node represents the result of the mflr at function entry,...
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ QVALIGNI
QVALIGNI = This corresponds to the QPX qvaligni instruction.
@ RET_FLAG
Return with a flag operand, matched by 'blr'.
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ QVESPLATI
QVESPLATI = This corresponds to the QPX qvesplati instruction.
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
unsigned getVSPLTImmediate(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getVSPLTImmediate - Return the appropriate VSPLT* immediate to splat the specified isSplatShuffleMask...
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
int isQVALIGNIShuffleMask(SDNode *N)
If this is a qvaligni shuffle mask, return the shift amount, otherwise return -1.
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Reg
All possible values of the reg field in the ModR/M byte.
const_iterator end(StringRef path)
Get end iterator over path.
This class represents lattice values for constants.
constexpr bool isUInt< 16 >(uint64_t x)
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAcquireOrStronger(AtomicOrdering ao)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
constexpr bool isInt< 16 >(int64_t x)
uint32_t FloatToBits(float Float)
This function takes a float and returns the bit equivalent 32-bit integer.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
@ Mod
The access may modify the value stored in memory.
@ Z
zlib style complession
FormattedString left_justify(StringRef Str, unsigned Width)
left_justify - append spaces after string so total output is Width characters.
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isReleaseOrStronger(AtomicOrdering ao)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
unsigned getScalarSizeInBits() const
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
bool isInConsecutiveRegs() const
unsigned getByValSize() const
bool isInConsecutiveRegsLast() const
unsigned getByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
void resetAll()
Resets the known state of all bits.
This class contains a discriminated union of information about pointers in memory operands,...
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
These are IR-level optimization flags that may be propagated to SDNodes.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)